commit a25359713ef73ad7e27a3d9f40ee1edfd6dcef43 Author: Zhang0626 Date: Sat Jul 30 11:50:01 2022 +0800 第一次提交 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d9c1309 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +ChaosDataPlayer/out/ diff --git a/ChaosDataPlayer/Adddeviceform.cpp b/ChaosDataPlayer/Adddeviceform.cpp new file mode 100644 index 0000000..2f46b4a --- /dev/null +++ b/ChaosDataPlayer/Adddeviceform.cpp @@ -0,0 +1,75 @@ +#include "Adddeviceform.h" +#include "ui_Adddeviceform.h" +#include +#include "cidwudp.h" +#include +#include +#include "QMessageBox" + +AddDeviceForm::AddDeviceForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::AddDeviceForm) +{ + ui->setupUi(m_pMainWgt); + resize(500,320); + setWindowTitle("增加终端"); + strIP = ""; + + connect(ui->Btn_AutoSearch, SIGNAL(clicked()), this, SLOT(AutoSearch())); + connect(ui->Btn_Search, SIGNAL(clicked()), this, SLOT(Search())); + connect(ui->Btn_OK, SIGNAL(clicked()), this, SLOT(AddDevice())); + connect(ui->Btn_Cancel, SIGNAL(clicked()), this, SLOT(Cancel())); + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.)" + "{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + QRegExpValidator *validator = new QRegExpValidator(rx, this); + ui->lineEdit->setValidator(validator); +} + +AddDeviceForm::~AddDeviceForm() +{ + delete ui; +} + +void AddDeviceForm::AutoSearch() +{ + emit AutoSearchIP(); +} +void AddDeviceForm::Search() +{ + ui->label_4->setText(""); + ui->label_5->setText(""); + strIP = ui->lineEdit->text(); + if(strIP == ""){ + MyMsgBox(QMessageBox::Question,"问题","请输入完整信息"); + return; + } + emit AddDeviceIP(strIP,false); +} +void AddDeviceForm::AddDevice() +{ + strIP = ui->lineEdit->text(); + if(strIP == ""){ + MyMsgBox(QMessageBox::Question,"问题","请输入完整信息"); + return; + } + emit AddDeviceIP(strIP,false); +} +void AddDeviceForm::UpdateDeviceInfo() +{ + qDebug() << "MacAddr_G:" << global::MacAddr_G; + ui->label_4->setText(global::MacAddr_G); + ui->label_5->setText("正常"); + qDebug() << "DeviceNO:" << DeviceNO; +} +void AddDeviceForm::Cancel() +{ + this->close(); +} +void AddDeviceForm::keyPressEvent(QKeyEvent *event) +{ + //Enter事件好像这两个都要写,只写event->key() == Qt::Key_Enter,无法实现 + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + Search(); + } +} diff --git a/ChaosDataPlayer/Adddeviceform.h b/ChaosDataPlayer/Adddeviceform.h new file mode 100644 index 0000000..41221d7 --- /dev/null +++ b/ChaosDataPlayer/Adddeviceform.h @@ -0,0 +1,36 @@ +#ifndef ADDDEVICEFORM_H +#define ADDDEVICEFORM_H + +#include +#include "BaseWgt.h" +#include +#include "msgbox.h" + +namespace Ui { +class AddDeviceForm; +} + +class AddDeviceForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit AddDeviceForm(QWidget *parent = nullptr); + ~AddDeviceForm(); + void UpdateDeviceInfo(); +private: + Ui::AddDeviceForm *ui; + QString strIP; +private slots: + void Search(); + void AutoSearch(); + void AddDevice(); + void Cancel(); +protected: + virtual void keyPressEvent(QKeyEvent *event); +signals: + void AddDeviceIP(QString,bool); + void AutoSearchIP(); +}; + +#endif // ADDDEVICEFORM_H diff --git a/ChaosDataPlayer/Adddeviceform.ui b/ChaosDataPlayer/Adddeviceform.ui new file mode 100644 index 0000000..bc1d717 --- /dev/null +++ b/ChaosDataPlayer/Adddeviceform.ui @@ -0,0 +1,198 @@ + + + AddDeviceForm + + + + 0 + 0 + 491 + 300 + + + + Form + + + #Btn_Search { border-image:url(:/images/images/imgModelAction/Search.png) 5; } +#Btn_Search:hover { border-image:url(:/images/images/imgModelAction/Search-h.png) 5; } +#Btn_Search:pressed {border-image:url(:/images/images/imgModelAction/Search-p.png) 5; } +#Btn_Search:checked {border-image:url(:/images/images/imgModelAction/Search.png) 5; } + + + + + + + 0 + 200 + + + + + + 170 + 50 + 151 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + + + + 113 + 50 + 61 + 31 + + + + IP地址 + + + + + + 110 + 100 + 61 + 31 + + + + 设备名称: + + + + + + 110 + 130 + 61 + 31 + + + + 设备状态: + + + + + + 330 + 50 + 31 + 31 + + + + background-image: url(:/images/images/imgModelAction/Search.png); + + + + + + + + + 190 + 110 + 141 + 16 + + + + + + + + + + 190 + 140 + 141 + 16 + + + + + + + + + + + + + 0 + 30 + + + + + + 270 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 确认 + + + + + + 370 + 40 + 75 + 23 + + + + Qt::LeftToRight + + + background-color: rgb(69, 90, 108); + + + 取消 + + + + + + 150 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 自动搜索 + + + + + + + + + diff --git a/ChaosDataPlayer/BaseWgt.cpp b/ChaosDataPlayer/BaseWgt.cpp new file mode 100644 index 0000000..17e7a03 --- /dev/null +++ b/ChaosDataPlayer/BaseWgt.cpp @@ -0,0 +1,413 @@ +#include "BaseWgt.h" +#include +#include +#include +#include +#include + +enum MouseStyle{ NORMAL, RIGHT, BOTTOMRIGHT, BOTTOM } mouseStyle; + +BaseWgt::BaseWgt(QWidget *parent) + : QWidget(parent) + , m_bResizable(true) + , m_iMarginWidth(6) + , m_bPressed(false) + , m_ptPressPos(0, 0) + , m_bIsMaxState(false) +{ + //this->setAttribute(Qt::WA_TranslucentBackground); + this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window); + + this->initUiControl(); + this->initSignalSlotConn(); + + this->setAttribute(Qt::WA_Hover); + this->installEventFilter(this); +} + +BaseWgt::~BaseWgt() +{ + +} + +bool BaseWgt::eventFilter(QObject *obj, QEvent *event) +{ + if (obj != this && obj != m_pTopWgt) + { + return false; + } + switch(event->type()) + { + case QEvent::MouseMove: + { + QMouseEvent *mouseEvent = dynamic_cast(event); + if (m_bPressed && mouseStyle == NORMAL && NULL != mouseEvent) + { + //如果是最大化,则先恢复正常状态 + if (m_bIsMaxState) + { + QPoint pt = this->mapFromGlobal(QCursor::pos()); + int iMaxWidth = this->width(); + + m_bIsMaxState = !m_bIsMaxState; + this->resize(m_normalRect.size()); + m_pMaxBtn->setProperty("maxState", false); + m_pMaxBtn->setToolTip("最大化"); + + QStyle *pStyle = this->style(); + pStyle->unpolish(m_pMaxBtn); + pStyle->polish(m_pMaxBtn); + + m_ptPressPos.setY(pt.y()); + m_ptPressPos.setX(pt.x() * (this->width() - 100) / (iMaxWidth - 100)); + } + this->move(this->mapToGlobal(mouseEvent->pos()) - m_ptPressPos); + return true; + } + break; + } + //[1]鼠标在界面上移动 + case QEvent::HoverMove: + { + QHoverEvent *hoverEvent = dynamic_cast(event); + if (m_bPressed) + { + //只能在界面右边或者右下角缩放界面 + QPoint ptGlobalPos = this->mapToGlobal(hoverEvent->pos()); + QPoint ptTopLeft = this->frameGeometry().topLeft(); + QPoint ptBottomRight = this->frameGeometry().bottomRight(); + switch(mouseStyle) + { + case BOTTOM: + if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight()) + { + ptBottomRight.setY(ptGlobalPos.y()); + } + else + { + ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight()); + } + break; + + case RIGHT: + if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth()) + { + ptBottomRight.setX(ptGlobalPos.x()); + } + else + { + ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth()); + } + break; + + + case BOTTOMRIGHT: + if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight()) + { + ptBottomRight.setY(ptGlobalPos.y()); + } + else + { + ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight()); + } + if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth()) + { + ptBottomRight.setX(ptGlobalPos.x()); + } + else + { + ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth()); + } + break; + } + this->setGeometry(QRect(ptTopLeft, ptBottomRight)); + return true; + } + else + { + changeMouseStyle(hoverEvent->pos()); + } + } + break; + //[1]end 鼠标在界面上移动 + + //[2]鼠标按下 + case QEvent::MouseButtonPress: + { + //在顶部/右方边缘/右下角时,鼠标按下时做标记 + QMouseEvent *mouseEvent = dynamic_cast(event); + if (mouseEvent->button() == Qt::LeftButton) + { + if (mouseEvent->pos().y() <= TOP_HEIGHT | mouseStyle != NORMAL) + { + qDebug()<<"pressed in"; + m_bPressed = true; + m_ptPressPos = mouseEvent->globalPos() - this->frameGeometry().topLeft(); + } + } + } + break; + //[2]end 鼠标按下 + + //[3]鼠标左键松开 + case QEvent::MouseButtonRelease: + { + QMouseEvent *mouseEvent = dynamic_cast(event); + if (mouseEvent->button() == Qt::LeftButton) + { + qDebug()<<"release in"; + m_bPressed = false; + changeMouseStyle(mouseEvent->pos()); + } + } + break; + //[3]end 鼠标左键松开 + + //[4]鼠标双击 + case QEvent::MouseButtonDblClick: + { + QMouseEvent *mouseEvent = dynamic_cast(event); + if (mouseEvent->button() == Qt::LeftButton && mouseEvent->pos().y() <= TOP_HEIGHT) + { + qDebug()<<"dbc in"; + maximumBtnClickedSlot(); + return true; + } + } + break; + //[4]鼠标双击 + + case QEvent::Show: + { + repaint(); + } + + default: + break; + } + return false; +} + +void BaseWgt::changeMouseStyle(const QPoint &ptMousePos) +{ + if (!m_bResizable) + { + setCursor(Qt::ArrowCursor);//正常样式 + mouseStyle = NORMAL; + return; + } + if (m_bIsMaxState) + { + setCursor(Qt::ArrowCursor);//正常样式 + mouseStyle = NORMAL; + return; + } + int iPosX = ptMousePos.x(); + int iPosY = ptMousePos.y(); + int iWidth = this->width(); + int iHeight = this->height(); + + if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth) + { + if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight) + { + setCursor(Qt::SizeFDiagCursor);//右下 + mouseStyle = BOTTOMRIGHT; + return; + } + setCursor(Qt::SizeHorCursor); + mouseStyle = RIGHT;//右 + return; + } + if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight) + { + setCursor(Qt::SizeVerCursor);//下 + mouseStyle = BOTTOM; + return; + } + setCursor(Qt::ArrowCursor); + mouseStyle = NORMAL; + return; +} + +//[4]设置是否可以伸缩 +void BaseWgt::setResizable(bool bResizable) +{ + m_bResizable = bResizable; +} +//[4]end 设置是否可以伸缩 + +//[5]设置鼠标样式在界面边缘改变的范围 +void BaseWgt::setMargin(const int &iMargin) +{ + m_iMarginWidth = iMargin; +} + +//[5]end 设置鼠标样式在界面边缘改变的范围 + +void BaseWgt::initUiControl() +{ + //设置使程序支持中文字符 + QTextCodec *codec = QTextCodec::codecForName("System"); // 获取系统编码 + QTextCodec::setCodecForLocale(codec); +// QTextCodec::setCodecForCStrings(codec); +// QTextCodec::setCodecForTr(codec); + + QDesktopWidget*pDeskTop = QApplication::desktop(); + if(pDeskTop->screenCount() >= 2) + { + m_screenRect = pDeskTop->screenGeometry(pDeskTop->primaryScreen() == 0?1:0); + } + else + { + m_screenRect = pDeskTop->availableGeometry();//保存屏幕大小 + } + + + + m_pBottomWgt = new QWidget(this); + m_pBottomWgt->setObjectName("m_pBottomWgt"); + + QVBoxLayout *pVBoxLayoutBottom = new QVBoxLayout(this); + pVBoxLayoutBottom->setMargin(0); + pVBoxLayoutBottom->setSpacing(0); + pVBoxLayoutBottom->addWidget(m_pBottomWgt); + + + + m_pTopWgt = new QWidget(this); + m_pTopWgt->installEventFilter(this); + m_pTopWgt->setObjectName("m_pTopWgt"); + m_pTopWgt->setMinimumHeight(TOP_HEIGHT); + m_pTopWgt->setMaximumHeight(TOP_HEIGHT); + //m_pTopWgt->setAttribute(Qt::WA_Hover); + + m_pMainWgt = new QWidget(this); + m_pMainWgt->setObjectName("m_pMainWgt"); + + QVBoxLayout *pVBoxLayout = new QVBoxLayout(m_pBottomWgt); + pVBoxLayout->setMargin(0); + pVBoxLayout->setSpacing(0); + pVBoxLayout->addWidget(m_pTopWgt); + pVBoxLayout->addWidget(m_pMainWgt); + + m_pIconLabel = new QLabel(this); + m_pTitleLbl = new QLabel(this); + m_pMinBtn = new QPushButton(this); + m_pMaxBtn = new QPushButton(this); + m_pCloseBtn = new QPushButton(this); + m_pIconLabel->setMinimumSize(20, 20); + m_pIconLabel->setMaximumSize(20, 20); + m_pMinBtn->setMinimumSize(27, 22); + m_pMinBtn->setMaximumSize(27, 22); + m_pMaxBtn->setMinimumSize(27, 22); + m_pMaxBtn->setMaximumSize(27, 22); + m_pCloseBtn->setMinimumSize(42, 22); + m_pCloseBtn->setMaximumSize(42, 22); + m_pMinBtn->setToolTip("最小化"); + m_pMaxBtn->setToolTip("最大化"); + m_pCloseBtn->setToolTip("关闭"); + m_pIconLabel->setObjectName("m_pIconLabel"); + m_pTitleLbl->setObjectName("m_pTitleLbl"); + m_pMinBtn->setObjectName("m_pMinBtn"); + m_pMaxBtn->setObjectName("m_pMaxBtn"); + m_pCloseBtn->setObjectName("m_pCloseBtn"); + + QHBoxLayout *pHBoxLayout = new QHBoxLayout; + pHBoxLayout->setContentsMargins(8, 2, 2, 2); + pHBoxLayout->setSpacing(1); + pHBoxLayout->addWidget(m_pIconLabel); + pHBoxLayout->addSpacing(5); + pHBoxLayout->addWidget(m_pTitleLbl); + pHBoxLayout->addStretch(); + pHBoxLayout->addWidget(m_pMinBtn); + pHBoxLayout->addWidget(m_pMaxBtn); + pHBoxLayout->addWidget(m_pCloseBtn); + m_pTopWgt->setLayout(pHBoxLayout); + + //载入样式表 + QFile file(WGT_STYLE_PATH); + if (file.open(QIODevice::ReadOnly)) + { + QString strSheet = file.readAll(); + setStyleSheet(strSheet); + } +} + +//初始化信号槽连接 +void BaseWgt::initSignalSlotConn() +{ + connect(m_pMinBtn, SIGNAL(clicked()), this, SLOT(minimumBtnClickedSlot())); + connect(m_pMaxBtn, SIGNAL(clicked()), this, SLOT(maximumBtnClickedSlot())); + connect(m_pCloseBtn, SIGNAL(clicked()), this, SLOT(close())); +} + + +//最小化按钮单击槽函数 +void BaseWgt::minimumBtnClickedSlot() +{ + showMinimized(); +} + +//最大化按钮单击槽函数 +void BaseWgt::maximumBtnClickedSlot() +{ + m_bIsMaxState = !m_bIsMaxState; + if (m_bIsMaxState) + { + //记录下正常窗口的状态 + m_normalRect.setTopLeft(this->frameGeometry().topLeft()); + m_normalRect.setSize(this->size()); + + this->setGeometry(m_screenRect); + m_pMaxBtn->setProperty("maxState", true); + m_pMaxBtn->setToolTip("restore"); + } + else + { + this->setGeometry(m_normalRect); + m_pMaxBtn->setProperty("maxState", false); + m_pMaxBtn->setToolTip("最大化"); + } + QStyle *pStyle = this->style(); + pStyle->unpolish(m_pMaxBtn); + pStyle->polish(m_pMaxBtn); +} + +void BaseWgt::setSysIcon(const QString &url) +{ + qDebug()<setPixmap(*pixmap); +} + +//设置窗口标题 +void BaseWgt::setWindowTitle(const QString &strTitle) +{ + m_pTitleLbl->setText(strTitle); + m_pTitleLbl->setFixedSize(m_pTitleLbl->sizeHint()); + m_pTitleLbl->setFixedHeight(22); +} + +void BaseWgt::hideTopWgt() +{ + m_pTopWgt->hide(); +} + +void BaseWgt::setTopWgtHiddent(bool bHide) +{ + if(bHide) + { + m_pTopWgt->hide(); + } + else + { + m_pTopWgt->show(); + } +} + +void BaseWgt::setCloseBtnVisible(bool bVisible) +{ + if(!m_pCloseBtn) return; + m_pCloseBtn->setVisible(bVisible); +} diff --git a/ChaosDataPlayer/BaseWgt.h b/ChaosDataPlayer/BaseWgt.h new file mode 100644 index 0000000..b9cc71f --- /dev/null +++ b/ChaosDataPlayer/BaseWgt.h @@ -0,0 +1,66 @@ +#ifndef BASEWGT_H +#define BASEWGT_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TOP_HEIGHT 25 +#define WGT_STYLE_PATH ":/qss/mainui.css" + +class BaseWgt : public QWidget +{ + Q_OBJECT +public: + BaseWgt(QWidget *parent = 0); + ~BaseWgt(); + void setResizable(bool bResizable); //设置是否可以伸缩 + void setMargin(const int &iMargin); //设置鼠标样式在界面边缘改变的范围 + void setSysIcon(const QString &url); + void setWindowTitle(const QString &); //设置窗口标题 + void hideTopWgt(); //隐藏标题 + void setTopWgtHiddent(bool bHide); + void setCloseBtnVisible(bool bVisible); + +protected: + virtual bool eventFilter(QObject *, QEvent *); + +private: + void changeMouseStyle(const QPoint &); //改变鼠标样式 + void initUiControl(); //初始化界面控件 + void initSignalSlotConn(); //初始化信号槽连接 + +private slots: + void minimumBtnClickedSlot(); //最小化按钮单击槽函数 + void maximumBtnClickedSlot(); //最大化按钮单击槽函数 + +protected: + QWidget *m_pTopWgt; //顶部 + QWidget *m_pBottomWgt; //底部窗口 + QWidget *m_pMainWgt; //主体 + QLabel *m_pIconLabel; //系统图标 + QPushButton *m_pMinBtn; //最小化 + QPushButton *m_pMaxBtn; //最大化 + QPushButton *m_pCloseBtn; //关闭 + QRect m_screenRect; //最大化窗口 + +private: + bool m_bResizable; //是否可拉伸 + int m_iMarginWidth; //边缘距离 + bool m_bPressed; //标记鼠标是否按下 + QPoint m_ptPressPos; //鼠标按下的位置 + bool m_bIsMaxState; //是否是最大化 + + + QLabel *m_pTitleLbl; //标题 + + QRect m_normalRect; //正常窗口 + +}; + +#endif // BASEWGT_H diff --git a/ChaosDataPlayer/Calculation.cpp b/ChaosDataPlayer/Calculation.cpp new file mode 100644 index 0000000..a37e25e --- /dev/null +++ b/ChaosDataPlayer/Calculation.cpp @@ -0,0 +1,700 @@ +#include "Calculation.hpp" +#define PI 3.1415926535 +Calculation::Calculation() +{ +} + +Calculation::~Calculation() +{ +} + +/************************************************************************/ +/* 一维数据的复数快速傅里叶变换 */ +/************************************************************************/ +void Calculation::FFT(int n, fftw_complex* in, fftw_complex* out) +{ + if (in == NULL || out == NULL) return; + fftw_plan p; + p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE); + fftw_execute(p); + fftw_destroy_plan(p); + fftw_cleanup(); +} + +/************************************************************************/ +/* 一维数据的实数快速傅里叶变换 */ +/************************************************************************/ +void Calculation::FFT_R(int n, QVector & vecData, fftw_complex* out) +{ + double in[n]; + for (int i = 0; i < n; i++) { + in[i] = vecData[i]; + } + + for (int i = 0; i < n; i++) + { + out[i][0] = (double)vecData[i]; + out[i][1] = 0; + } + //create a DFT plan and execute it + fftw_plan plan = fftw_plan_dft_r2c_1d(n, in, out, FFTW_ESTIMATE); + fftw_execute(plan); + //destroy the plan to prevent a memory leak + fftw_destroy_plan(plan); + fftw_cleanup(); +} + +/************************************************************************/ +/* 一维数据的快速傅里叶逆变换 */ +/************************************************************************/ +void Calculation::iFFT(int n, fftw_complex* in, fftw_complex* out) +{ + if (in == NULL || out == NULL) return; + fftw_plan p; + p = fftw_plan_dft_1d(n, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); + fftw_execute(p); + fftw_destroy_plan(p); + fftw_cleanup(); +} + +//************************************ +// Method: caculateAmp_Pha +// FullName: Calculation::caculateAmp_Pha +// Access: public static +// Returns: void +// Qualifier: +// Parameter: int n +// Parameter: fftw_complex * in +// Parameter: int frequency +// Parameter: double & amplitude +// Parameter: double & phase +// 函数功能是计算特定频率的幅值和相位,原来的讨论中是传入一个特定的频率,然后在给定的频率左右范围内找幅值和相位 +// 目前的函数实现是计算FFT变换后特定点的幅值和相位 +// 然后还有一个地方需要修改,即给定频率和FFT变换结果序列 +//************************************ +void Calculation::caculateAmp_Pha(int n, fftw_complex* in, int frequency, double &litude, double &phase) +{ + int index = frequency; + amplitude = 2 * sqrt((in[index][0] / n) * (in[index][0] / n) + (in[index][1] / n) * (in[index][1] / n)); + phase = 180 * atan(in[index][1] / in[index][0]) / M_PI; +} + + +void Calculation::absVec(QVector & vecAbsData,QVector & vecData) +{ + for (int i = 0; i < vecData.size(); i++) { + vecAbsData.push_back(fabs(vecData[i])); + } + return; +} + + +float Calculation::mean(QVector & vecData) +{ + double meanTemp = 0; + for (int i = 0; i < vecData.size(); i++) { + meanTemp += (double)vecData[i]; + } + return meanTemp / vecData.size(); +} + + +void Calculation::drop_mean(QVector & vecDropMeanData, QVector & vecData) +{ + float fMean = mean(vecData); + for (int i = 0; i < vecData.size(); i++) { + vecDropMeanData.push_back(vecData[i] - fMean); + } + return; +} + +float Calculation::srm(QVector & vecData) +{ + double dSrmTemp = 0; + for (int i = 0; i < vecData.size(); i++){ + dSrmTemp = dSrmTemp + sqrt(vecData[i]); + } + dSrmTemp = dSrmTemp / vecData.size(); + return dSrmTemp * dSrmTemp; +} + + +float Calculation::rms(QVector & vecData) +{ + double rmsTemp = 0; + for (int i = 0; i < vecData.size(); i++) { + rmsTemp = rmsTemp += (vecData[i] * vecData[i]); + } + rmsTemp = rmsTemp / vecData.size(); + return sqrt(rmsTemp); +} + + +float Calculation::variance(QVector & vecDropMeanData) +{ + double varianceTemp = 0; + for (int i = 0; i < vecDropMeanData.size(); i++) { + varianceTemp = varianceTemp += (vecDropMeanData[i] * vecDropMeanData[i]); + } + return varianceTemp/vecDropMeanData.size(); +} + +float Calculation::skew_state(QVector & vecDropMeanData, float fVariance) +{ + double tempSkew = 0; + for (int i = 0; i < vecDropMeanData.size(); i++) { + tempSkew = tempSkew + pow(vecDropMeanData[i], 3); + } + tempSkew = tempSkew / vecDropMeanData.size(); + tempSkew = tempSkew / pow(fVariance, 1.5); + return tempSkew; +} + + +float Calculation::kurtosis(QVector & vecDropMeanData, float fVariance) +{ + double tempkurtosis = 0; + for (int i = 0; i < vecDropMeanData.size(); i++) { + tempkurtosis = tempkurtosis + pow(vecDropMeanData[i], 4); + } + tempkurtosis = tempkurtosis / vecDropMeanData.size(); + tempkurtosis = tempkurtosis / pow(fVariance, 2); + return tempkurtosis; +} + +void Calculation::hilbert(QVector & vecData, QVector & vecHilbertData, int N) +{ + + double in[N]; + for (int i = 0; i < N; i++) { + in[i] = vecData[i]; + } + fftw_complex *out; + out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); + + for (int i = 0; i < N; ++i) + { + out[i][0] = (double)vecData[i]; + out[i][1] = 0; + } + //create a DFT plan and execute it + fftw_plan plan = fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE); + fftw_execute(plan); + //destroy the plan to prevent a memory leak + fftw_destroy_plan(plan); + int hN = N >> 1; // half of the length (N /2) + int numRem = hN; // the number of remaining elements + // multiply the appropriate values by 2 + // (those that should be multiplied by 1 are left intact because they wouldn't change) + for (int i = 1; i < hN; ++i) // 1,2,...,N/2 - 1 的项乘以2 + { + out[i][0] *= 2; + out[i][1] *= 2; + } + // if the length is even, the number of remaining elements decreases by 1 + if (N % 2 == 0) + numRem--; + // if it's odd and greater than 1, the middle value must be multiplied by 2 + else if (N > 1) // 奇数非空 + { + out[hN][0] *= 2; + out[hN][1] *= 2; + } + // set the remaining values to 0 + // (multiplying by 0 gives 0, so we don't care about the multiplicands) + memset(&out[hN + 1][0], 0, numRem * sizeof(fftw_complex)); + // create an IDFT plan and execute it + plan = fftw_plan_dft_1d(N, out, out, FFTW_BACKWARD, FFTW_ESTIMATE); + fftw_execute(plan); + // do some cleaning + fftw_destroy_plan(plan); + fftw_cleanup(); + // scale the IDFT output + for (int i = 0; i < N; ++i) + { + out[i][0] /= N; + out[i][1] /= N; + } + + for( int n=0; n & vecData, QVector & vecFFTSpecData) +{ + fftw_complex *inFFt, *outFFt; + inFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + outFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + + for (int j = 0; j < vecData.size(); j++) { + inFFt[j][0] = (double)vecData[j]; + inFFt[j][1] = 0; + } + FFT(vecData.size(),inFFt, outFFt); + for(int j = 0; j < vecData.size()/2; j++) { + vecFFTSpecData.push_back(sqrt(outFFt[j][0]*outFFt[j][0] + outFFt[j][1]*outFFt[j][1])*2/vecData.size()); + } + fftw_free(inFFt); + fftw_free(outFFt); +} +void Calculation::_iFFT( QVector & vecrealData,QVector & vecimageData,QVector & veciFFTData) +{ + fftw_complex *inFFt, *outFFt; + int N = vecrealData.size(); + inFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); + outFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); + + for (int j = 0; j < N; j++) { + inFFt[j][0] = (double)vecrealData[j]; + inFFt[j][1] = (double)vecimageData[j]; + } + iFFT(N,inFFt, outFFt); + for (int i = 0; i < N; i++) { + outFFt[i][0] *= 1./N; + outFFt[i][1] *= 1./N; + veciFFTData.push_back(outFFt[i][0]); + } + fftw_free(inFFt); + fftw_free(outFFt); +} + +void Calculation::_FFT(QVector & vecData, QVector & vecFFTrealData,QVector & vecFFTimageData) +{ + fftw_complex *inHilFFt, *outHilFFt; + inHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + outHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + + for (int j = 0; j < vecData.size(); j++) { + inHilFFt[j][0] = (double)vecData[j]; + inHilFFt[j][1] = 0; + } + + FFT(vecData.size(), inHilFFt, outHilFFt); + //fftShift(outHilFFt, vecData.size()); + for (int i = 0; i < vecData.size(); i++) { + vecFFTrealData.push_back(outHilFFt[i][0]); + vecFFTimageData.push_back(outHilFFt[i][1]); + } + fftw_free(inHilFFt); + fftw_free(outHilFFt); +} + + +void Calculation::_fft(QVector & vecData, QVector & vecFFTrealData,QVector & vecFFTimageData) +{ + fftw_complex *inHilFFt, *outHilFFt; + inHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + outHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + + for (int j = 0; j < vecData.size(); j++) { + inHilFFt[j][0] = (double)vecData[j]; + inHilFFt[j][1] = 0; + } + + FFT(vecData.size(), inHilFFt, outHilFFt); + fftShift(outHilFFt, vecData.size()); + for (int i = 0; i < vecData.size(); i++) { + vecFFTrealData.push_back(outHilFFt[i][0]); + vecFFTimageData.push_back(outHilFFt[i][1]); + } + fftw_free(inHilFFt); + fftw_free(outHilFFt); +} + +void Calculation::envSpec(QVector & vecData, QVector & vecEnvSpecData,int StartFrequency,int EndFrequency,bool PolarPlot) +{ + + QVector vecFFTrealData,vecFFTimageData; + QVector vecRealData,vecImageData; + QVector veciFFtData; + QVector veciFFtData2; + QVector vecHilbertData; + _FFT(vecData,vecFFTrealData,vecFFTimageData); + for(int i = 0; i < vecFFTrealData.size();i++){ + + if(i < StartFrequency || i > EndFrequency){ + vecFFTrealData.replace(i,0.0); + vecFFTimageData.replace(i,0.0); + } + } + _iFFT(vecFFTrealData,vecFFTimageData,veciFFtData); + + for(int j = 0; j < veciFFtData.size();j++){ + veciFFtData2.push_back(veciFFtData[j]*2); + } + + if(!PolarPlot){ + hilbert(veciFFtData2,vecHilbertData,veciFFtData2.size()); + FFTSpec(vecHilbertData, vecEnvSpecData); + }else{ + + vecEnvSpecData = veciFFtData2; + } + +} +//w(n) = 0.5 – 0.5*cos(2*πn/N); for n=0,1,2,…………………………N-1 +void Calculation::Hanning(QVector & vecData,QVector & vecHanningData) +{ + int N = vecData.size(); + + float* w = NULL; + w = (float*)calloc(N, sizeof(float)); + int half, i, idx; + if (N % 2 == 0) + { + half = N / 2; + for (i = 0; i < half; i++) //CALC_HANNING Calculates Hanning window samples. + w[i] = 0.5 * (1 - cos(2 * PI * (i + 1) / (N + 1))); + + + idx = half - 1; + for (i = half; i < N; i++) { + w[i] = w[idx]; + idx--; + } + } + else + { + half = (N + 1) / 2; + for (i = 0; i < half; i++) //CALC_HANNING Calculates Hanning window samples. + w[i] = 0.5 * (1 - cos(2 * PI * (i + 1) / (N + 1))); + + idx = half - 2; + for (i = half; i < N; i++) { + w[i] = w[idx]; + idx--; + } + } + for(int j = 0; j < N;j++){ + vecHanningData.push_back(w[j]); + } + free(w); +} + +double Calculation::Phase(QVector & vecData) +{ + fftw_complex *inHilFFt, *outHilFFt; + inHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + outHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); + + for (int j = 0; j < vecData.size(); j++) { + inHilFFt[j][0] = (double)vecData[j]; + inHilFFt[j][1] = 0; + } + + FFT(vecData.size(), inHilFFt, outHilFFt); + QVector vecFFTrealData; + QVector vecFFTimageData; + for (int i = 0; i < vecData.size(); i++) { + vecFFTrealData.push_back(outHilFFt[i][0]); + vecFFTimageData.push_back(outHilFFt[i][1]); + } + fftw_free(inHilFFt); + fftw_free(outHilFFt); + + double Phase1 = atan2(vecFFTrealData[0],vecFFTimageData[0]) *180/PI; + double Phase2 = atan2(vecFFTrealData[vecData.size()-1],vecFFTimageData[vecData.size()-1]) *180/PI; + return Phase2 - Phase1; +} + +QVector Calculation::ComputeDenCoeffs(int FilterOrder, double Lcutoff, double Ucutoff) +{ + int k; // loop variables + double theta; // PI * (Ucutoff - Lcutoff) / 2.0 + double cp; // cosine of phi + double st; // sine of theta + double ct; // cosine of theta + double s2t; // sine of 2*theta + double c2t; // cosine 0f 2*theta + QVector RCoeffs(2 * FilterOrder); // z^-2 coefficients + QVector TCoeffs(2 * FilterOrder); // z^-1 coefficients + QVector DenomCoeffs; // dk coefficients + double PoleAngle; // pole angle + double SinPoleAngle; // sine of pole angle + double CosPoleAngle; // cosine of pole angle + double a; // workspace variables + + cp = cos(PI * (Ucutoff + Lcutoff) / 2.0); + theta = PI * (Ucutoff - Lcutoff) / 2.0; + st = sin(theta); + ct = cos(theta); + s2t = 2.0*st*ct; // sine of 2*theta + c2t = 2.0*ct*ct - 1.0; // cosine of 2*theta + + for (k = 0; k < FilterOrder; ++k) + { + PoleAngle = PI * (double)(2 * k + 1) / (double)(2 * FilterOrder); + SinPoleAngle = sin(PoleAngle); + CosPoleAngle = cos(PoleAngle); + a = 1.0 + s2t*SinPoleAngle; + RCoeffs[2 * k] = c2t / a; + RCoeffs[2 * k + 1] = s2t*CosPoleAngle / a; + TCoeffs[2 * k] = -2.0*cp*(ct + st*SinPoleAngle) / a; + TCoeffs[2 * k + 1] = -2.0*cp*st*CosPoleAngle / a; + } + + DenomCoeffs = TrinomialMultiply(FilterOrder, TCoeffs, RCoeffs); + + DenomCoeffs[1] = DenomCoeffs[0]; + DenomCoeffs[0] = 1.0; + for (k = 3; k <= 2 * FilterOrder; ++k) + DenomCoeffs[k] = DenomCoeffs[2 * k - 2]; + + for (int i = DenomCoeffs.size() - 1; i > FilterOrder * 2 + 1; i--) + DenomCoeffs.pop_back(); + + return DenomCoeffs; +} + +QVector Calculation::TrinomialMultiply(int FilterOrder, QVector& b, QVector& c) +{ + int i, j; + QVector RetVal(4 * FilterOrder); + + RetVal[2] = c[0]; + RetVal[3] = c[1]; + RetVal[0] = b[0]; + RetVal[1] = b[1]; + + for (i = 1; i < FilterOrder; ++i) + { + RetVal[2 * (2 * i + 1)] += c[2 * i] * RetVal[2 * (2 * i - 1)] - c[2 * i + 1] * RetVal[2 * (2 * i - 1) + 1]; + RetVal[2 * (2 * i + 1) + 1] += c[2 * i] * RetVal[2 * (2 * i - 1) + 1] + c[2 * i + 1] * RetVal[2 * (2 * i - 1)]; + + for (j = 2 * i; j > 1; --j) + { + RetVal[2 * j] += b[2 * i] * RetVal[2 * (j - 1)] - b[2 * i + 1] * RetVal[2 * (j - 1) + 1] + + c[2 * i] * RetVal[2 * (j - 2)] - c[2 * i + 1] * RetVal[2 * (j - 2) + 1]; + RetVal[2 * j + 1] += b[2 * i] * RetVal[2 * (j - 1) + 1] + b[2 * i + 1] * RetVal[2 * (j - 1)] + + c[2 * i] * RetVal[2 * (j - 2) + 1] + c[2 * i + 1] * RetVal[2 * (j - 2)]; + } + + RetVal[2] += b[2 * i] * RetVal[0] - b[2 * i + 1] * RetVal[1] + c[2 * i]; + RetVal[3] += b[2 * i] * RetVal[1] + b[2 * i + 1] * RetVal[0] + c[2 * i + 1]; + RetVal[0] += b[2 * i]; + RetVal[1] += b[2 * i + 1]; + } + + return RetVal; +} + +QVector Calculation::ComputeNumCoeffs(int FilterOrder, double Lcutoff, double Ucutoff, QVector& DenC) +{ + QVector TCoeffs; + QVector NumCoeffs(2 * FilterOrder + 1); + QVector> NormalizedKernel(2 * FilterOrder + 1); + + QVector Numbers; + for (double n = 0; n < FilterOrder * 2 + 1; n++) + Numbers.push_back(n); + int i; + + TCoeffs = ComputeHP(FilterOrder); + + for (i = 0; i < FilterOrder; ++i) + { + NumCoeffs[2 * i] = TCoeffs[i]; + NumCoeffs[2 * i + 1] = 0.0; + } + NumCoeffs[2 * FilterOrder] = TCoeffs[FilterOrder]; + + double cp[2]; + double Bw, Wn; + cp[0] = 2 * 2.0*tan(PI * Lcutoff / 2.0); + cp[1] = 2 * 2.0*tan(PI * Ucutoff / 2.0); + + Bw = cp[1] - cp[0]; + //center frequency + Wn = sqrt(cp[0] * cp[1]); + Wn = 2 * atan2(Wn, 4); + double kern; + const std::complex result = std::complex(-1, 0); + + for (int k = 0; k< FilterOrder * 2 + 1; k++) + { + NormalizedKernel[k] = std::exp(-sqrt(result)*Wn*Numbers[k]); + } + double b = 0; + double den = 0; + for (int d = 0; d < FilterOrder * 2 + 1; d++) + { + b += real(NormalizedKernel[d] * NumCoeffs[d]); + den += real(NormalizedKernel[d] * DenC[d]); + } + for (int c = 0; c < FilterOrder * 2 + 1; c++) + { + NumCoeffs[c] = (NumCoeffs[c] * den) / b; + } + + for (int i = NumCoeffs.size() - 1; i > FilterOrder * 2 + 1; i--) + NumCoeffs.pop_back(); + + return NumCoeffs; +} + +QVector Calculation::ComputeLP(int FilterOrder) +{ + QVector NumCoeffs(FilterOrder + 1); + int m; + int i; + + NumCoeffs[0] = 1; + NumCoeffs[1] = FilterOrder; + m = FilterOrder / 2; + for (i = 2; i <= m; ++i) + { + NumCoeffs[i] = (double)(FilterOrder - i + 1)*NumCoeffs[i - 1] / i; + NumCoeffs[FilterOrder - i] = NumCoeffs[i]; + } + NumCoeffs[FilterOrder - 1] = FilterOrder; + NumCoeffs[FilterOrder] = 1; + + return NumCoeffs; +} + +QVector Calculation::ComputeHP(int FilterOrder) +{ + QVector NumCoeffs; + int i; + + NumCoeffs = ComputeLP(FilterOrder); + + for (i = 0; i <= FilterOrder; ++i) + if (i % 2) NumCoeffs[i] = -NumCoeffs[i]; + + return NumCoeffs; +} + +//vector filter(int ord, vector a, vector b, vector x) +//{ +// int np = x.size(); +// vector y(np); +// +// int i, j; +// y[0] = b[0] * x[0]; +// for (i = 1; i Calculation::filter(QVector&x, QVector& coeff_b, QVector& coeff_a) +{ + int len_x = x.size(); + int len_b = coeff_b.size(); + int len_a = coeff_a.size(); + + QVector zi(len_b); + + QVector filter_x(len_x); + + if (len_a == 1) + { + for (int m = 0; m bandpass(vector input, double lowpass, double highpass, double fps) +//{ +// double N = input.size(); +// cv::Mat x = cv::Mat::zeros(1, input.size(), CV_64FC1); +// +// for (int i = 0; i < input.size(); i++) +// { +// x.at(0, i) = input[i]; +// } +// +// Mat x_fre; +// dft(x, x_fre, DFT_COMPLEX_OUTPUT); +// +// Mat W = Mat::zeros(1, input.size(), CV_64FC1); +// +// for (int i = 0; i < input.size(); i++) +// { +// if ((double)i / N *) +// } +//} + +void Calculation::ButterWorth(QVector&inData,double *FrequencyBands,QVector& outData) +{ + int FiltOrd = 4; + QVector a,b; + + a = ComputeDenCoeffs(FiltOrd, FrequencyBands[0], FrequencyBands[1]); + + b = ComputeNumCoeffs(FiltOrd, FrequencyBands[0], FrequencyBands[1], a); + + outData = filter(inData,b,a); +} + + + + + + + + + + + + + diff --git a/ChaosDataPlayer/Calculation.hpp b/ChaosDataPlayer/Calculation.hpp new file mode 100644 index 0000000..b803604 --- /dev/null +++ b/ChaosDataPlayer/Calculation.hpp @@ -0,0 +1,104 @@ +#ifndef CALCULATION_H_ +#define CALCULATION_H_ + +#include +#include +#include +#include "fftw3.h" +#include +#include + +typedef struct +{ + float real,imag; +}complex; + +class Calculation +{ +public: + Calculation(); + ~Calculation(); + + //将数据取绝对值 + void absVec(QVector & vecAbsData, QVector & vecData); + + //将数据取平均值 + static float mean(QVector & vecData); + + //将数据平方处理 数据有效值 + float rms(QVector & vecData); + + //去数据的直流分量 + static void drop_mean(QVector & vecDropMeanData, QVector & vecData); + + //方根幅值 + float srm(QVector & vecData); + + //方差 + float variance(QVector & vecDropMeanData); + + //偏态指标 + float skew_state(QVector & vecDropMeanData, float fVariance); + + //峭度指标 + float kurtosis(QVector & vecDropMeanData, float fVariance); + + //快速傅里叶变换函数 + static void FFT(int n, fftw_complex* in, fftw_complex* out); + + //快速傅里叶实数变换函数 + void FFT_R(int n, QVector & vecData, fftw_complex* out); + + //快速傅里叶逆变换 + void iFFT(int n, fftw_complex* in, fftw_complex* out); + + //通道幅值和相位提取 + //输入为FFT变换后的数据长度及数据,指定的频率,输出为计算后得到的幅值 和 相位 + void caculateAmp_Pha(int n, fftw_complex* in, int frequency, double &litude, double &phase); + + //希尔伯特变换 + static void hilbert(QVector & vecData, QVector & vecHilbertData, int N); + + //FFT shift + static void fftShift(fftw_complex* in, int l); + + + //频谱图数据 + static void FFTSpec(QVector & vecData, QVector & vecFFTSpecData); + + + void _FFT(QVector & vecData, QVector & vecFFTrealData,QVector & vecFFTimageData); + void _fft(QVector & vecData, QVector & vecFFTrealData,QVector & vecFFTimageData); + void _iFFT(QVector & vecData, QVector & vecFFTSpecData,QVector & veciFFTData); + + + //包络图谱数据 + void envSpec(QVector & vecData, QVector & vecEnvSpecData,int StartFrequency,int EndFrequency,bool PolarPlot=false); + + //hanning 窗 + void Hanning(QVector & vecData,QVector & vecHanningData); + + //相位计算 + double Phase(QVector & vecData); + + QVector ComputeDenCoeffs(int FilterOrder, double Lcutoff, double Ucutoff); + + QVector TrinomialMultiply(int FilterOrder, QVector& b, QVector& c); + + QVector ComputeNumCoeffs(int FilterOrder, double Lcutoff, double Ucutoff, QVector& DenC); + + QVector ComputeLP(int FilterOrder); + + QVector ComputeHP(int FilterOrder); + + //vector filter(int ord, vector a, vector b, int np, vector x); + //巴特沃斯滤波 + QVector filter(QVector&x, QVector& coeff_b, QVector& coeff_a); + + void ButterWorth(QVector& inData,double *FrequencyBands,QVector& outData); + +}; + +#endif + + diff --git a/ChaosDataPlayer/ChaosDataPlayer.pro b/ChaosDataPlayer/ChaosDataPlayer.pro new file mode 100644 index 0000000..2846d13 --- /dev/null +++ b/ChaosDataPlayer/ChaosDataPlayer.pro @@ -0,0 +1,121 @@ +QT += core gui charts script axcontainer network multimedia + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport opengl sql + + +CONFIG += c++11 +RC_FILE += ICON.rc +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +#DEFINES += QT_DEPRECATED_WARNINGS +#DEFINES += GSL_DLL +DEFINES += QCUSTOMPLOT_USE_OPENGL +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + Adddeviceform.cpp \ + BaseWgt.cpp \ + Calculation.cpp \ + ChartView.cpp \ + ChildForm.cpp \ + CreateReport.cpp \ + DataParsing.cpp \ + FilterForm.cpp \ + LegendForm.cpp \ + LoadingDialog.cpp \ + MqttClient.cpp \ + NetMgr.cpp \ + PlayWaveSound.cpp \ + Reportform.cpp \ + SetScalesform.cpp \ + SettingForm.cpp \ + WordOperate.cpp \ + cidwudp.cpp \ + global.cpp \ + main.cpp \ + MainWidget.cpp \ + msgbox.cpp \ + qcustomplot.cpp \ + secure.cpp \ + sqlitedb.cpp + +HEADERS += \ + Adddeviceform.h \ + BaseWgt.h \ + Calculation.hpp \ + ChartView.h \ + ChildForm.h \ + CreateReport.h \ + DataParsing.h \ + FilterForm.h \ + LegendForm.h \ + LoadingDialog.h \ + MainWidget.h \ + MqttClient.h \ + NetMgr.h \ + PlayWaveSound.h \ + Reportform.h \ + ResizableWiget.h \ + SH_MySingleton.hpp \ + SetScalesform.h \ + SettingForm.h \ + WordOperate.h \ + cidwudp.h \ + fftw3.h \ + global.h \ + msgbox.h \ + qcustomplot.h \ + secure.h \ + sqlitedb.h + +FORMS += \ + Adddeviceform.ui \ + ChildForm.ui \ + FilterForm.ui \ + LegendForm.ui \ + MainWidget.ui \ + Reportform.ui \ + SetScalesForm.ui \ + SettingForm.ui \ + WebForm.ui + + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -lfreeglut +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/ -lfreeglut +else:unix: LIBS += -L$$PWD/lib/ + +INCLUDEPATH += $$PWD/. +INCLUDEPATH += $$PWD/GSL/include +DEPENDPATH += $$PWD/. +INCLUDEPATH += $$PWD/mqtt + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + qrc.qrc + +LIBS += -L$$PWD/fftwlib/ -llibfftw3-3 -llibfftw3f-3 -llibfftw3l-3 +LIBS += -lopengl32 -lglu32 -lglut +LIBS += -L$$PWD/GSL/lib/ -llibgsl -llibgslcblas +#LIBS += -LD:C:\Qt\Qt5.12.11\5.12.11\mingw73_32\lib -lopengl32 + + +unix|win32: LIBS += -L$$PWD/lib/ -lportaudio + +INCLUDEPATH += $$PWD/include +DEPENDPATH += $$PWD/include + +win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/MQTT/ -lQt5Qmqtt +else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/lib/MQTT/ -lQt5Qmqttd +else:unix: LIBS += -L$$PWD/lib/MQTT/ -lQt5Qmqtt + +INCLUDEPATH += $$PWD/lib/MQTT +DEPENDPATH += $$PWD/lib/MQTT diff --git a/ChaosDataPlayer/ChartView.cpp b/ChaosDataPlayer/ChartView.cpp new file mode 100644 index 0000000..5491f15 --- /dev/null +++ b/ChaosDataPlayer/ChartView.cpp @@ -0,0 +1,159 @@ +#include "ChartView.h" +#include +#include + +ChartView::ChartView( QWidget *parent) + : QChartView( parent) +{ + m_isPress = false; + m_ctrlPress = false; + m_alreadySaveRange = false; + m_coordItem = nullptr; + + this->setDragMode(QGraphicsView::RubberBandDrag); + this->setMouseTracking(false); + setCursor(QCursor(Qt::PointingHandCursor)); //设置鼠标指针为手指形 +} + +ChartView::~ChartView() +{ +} +void ChartView::SetChart(QChart *chart){ + setChart(chart); +} +void ChartView::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + m_lastPoint = event->pos(); + m_isPress = true; + } +} + +void ChartView::mouseMoveEvent(QMouseEvent *event) +{ + if (!m_coordItem) + { + m_coordItem = new QGraphicsSimpleTextItem(this->chart()); + m_coordItem->setZValue(5); + m_coordItem->setPos(100, 20); + m_coordItem->show(); + } + const QPoint curPos = event->pos(); + QPointF curVal = this->chart()->mapToValue(QPointF(curPos)); + QString coordStr = QString("X = %1, Y = %2").arg(curVal.x()).arg(curVal.y()); + m_coordItem->setText(coordStr); + + if (m_isPress) + { + QPoint offset = curPos - m_lastPoint; + m_lastPoint = curPos; + if (!m_alreadySaveRange) + { + this->saveAxisRange(); + m_alreadySaveRange = true; + } + this->chart()->scroll(-offset.x(), offset.y()); + } +} + +void ChartView::mouseReleaseEvent(QMouseEvent *event) +{ + m_isPress = false; + if (event->button() == Qt::RightButton) + { + if (m_alreadySaveRange) + { + this->chart()->axisX()->setRange(m_xMin, m_xMax); + this->chart()->axisY()->setRange(m_yMin, m_yMax); + } + }else if(event->button() == Qt::LeftButton) + { + return; + } +} + +void ChartView::wheelEvent(QWheelEvent *event) +{ + const QPoint curPos = event->pos(); + QPointF curVal = this->chart()->mapToValue(QPointF(curPos)); + + if (!m_alreadySaveRange) + { + this->saveAxisRange(); + m_alreadySaveRange = true; + } + + const double factor = 1.5;//缩放比例 + if (m_ctrlPress) + {//Y轴 + QValueAxis *axisY = dynamic_cast(this->chart()->axisY()); + const double yMin = axisY->min(); + const double yMax = axisY->max(); + const double yCentral = curVal.y(); + + double bottomOffset; + double topOffset; + if (event->delta() > 0) + {//放大 + bottomOffset = 1.0 / factor * (yCentral - yMin); + topOffset = 1.0 / factor * (yMax - yCentral); + } + else + {//缩小 + bottomOffset = 1.0 * factor * (yCentral - yMin); + topOffset = 1.0 * factor * (yMax - yCentral); + } + + this->chart()->axisY()->setRange(yCentral - bottomOffset, yCentral + topOffset); + } + else + {//X轴 + QValueAxis *axisX = dynamic_cast(this->chart()->axisX()); + const double xMin = axisX->min(); + const double xMax = axisX->max(); + const double xCentral = curVal.x(); + + double leftOffset; + double rightOffset; + if (event->delta() > 0) + {//放大 + leftOffset = 1.0 / factor * (xCentral - xMin); + rightOffset = 1.0 / factor * (xMax - xCentral); + } + else + {//缩小 + leftOffset = 1.0 * factor * (xCentral - xMin); + rightOffset = 1.0 * factor * (xMax - xCentral); + } + + this->chart()->axisX()->setRange(xCentral - leftOffset, xCentral + rightOffset); + } +} + +void ChartView::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Control) + { + m_ctrlPress = true; + } +} + +void ChartView::keyReleaseEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Control) + { + m_ctrlPress = false; + } +} + +void ChartView::saveAxisRange() +{ + QValueAxis *axisX = dynamic_cast(this->chart()->axisX()); + m_xMin = axisX->min(); + m_xMax = axisX->max(); + QValueAxis *axisY = dynamic_cast(this->chart()->axisY()); + m_yMin = axisY->min(); + m_yMax = axisY->max(); +} + diff --git a/ChaosDataPlayer/ChartView.h b/ChaosDataPlayer/ChartView.h new file mode 100644 index 0000000..2843bec --- /dev/null +++ b/ChaosDataPlayer/ChartView.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +QT_CHARTS_USE_NAMESPACE + +class ChartView : public QChartView +{ + Q_OBJECT + +public: + ChartView(QWidget *parent = nullptr); + ~ChartView(); + void SetChart(QChart *chart); + // 保存坐标区域,用于复位 + void saveAxisRange(); + QGraphicsSimpleTextItem* m_coordItem; +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + +private: + QPoint m_lastPoint; + bool m_isPress; + bool m_ctrlPress; + bool m_alreadySaveRange; + double m_xMin, m_xMax, m_yMin, m_yMax; +// QGraphicsSimpleTextItem* m_coordItem; +}; diff --git a/ChaosDataPlayer/Child3dFrom.cpp b/ChaosDataPlayer/Child3dFrom.cpp new file mode 100644 index 0000000..0ad3c76 --- /dev/null +++ b/ChaosDataPlayer/Child3dFrom.cpp @@ -0,0 +1,59 @@ +#include "Child3dFrom.h" +#include "ui_Child3dFrom.h" +#include "mylineplot3d.h" +#include + +Child3DFrom::Child3DFrom(QWidget *parent) : + QWidget(parent), + ui(new Ui::Child3DFrom) +{ + ui->setupUi(this); + connect(ui->ChannelBtn, SIGNAL(clicked()), this, SLOT(ChannelBtnSlot())); //打开通道选择 + ui->ChannelWgt->setVisible(false); + ui->tableWidget->setColumnWidth(0, 180); + ui->tableWidget->setColumnWidth(1, 40); + + myL3d = new mylineplot3d(); + QVBoxLayout * qvl = new QVBoxLayout(ui->widget_4); + qvl->addWidget(myL3d); + this->setLayout(qvl); + myL3d->init(); + myL3d->resize(800,600); + this->resize(800,600); + Qwt3D::Line3D l3d; + + mypL3d_1 = dynamic_cast< Qwt3D::Line3D*>(myL3d->addEnrichment(l3d)); + + myL3d->init(); + myL3d->coordinates()->setGridLines(true,true,Qwt3D::LEFT|Qwt3D::BACK|Qwt3D::FLOOR); + + myL3d->setTitle(tr("瀑布图")); + + mypL3d_1->configure(3,true); + + mypL3d_1->setLineColor(Qwt3D::RGBA(0,0,1,1)); + myL3d->setCurMaxMin(0,1000,0,20,0,60); + mypL3d_1->add(Qwt3D::Triple(x,y,z)); + + myL3d->tick(); + +} + +Child3DFrom::~Child3DFrom() +{ + delete ui; +} +void Child3DFrom::ChannelBtnSlot() +{ + ui->ChannelWgt->setVisible(!ui->ChannelWgt->isVisible()); + QString strStyle; + if(ui->ChannelWgt->isVisible()) + { + strStyle = "#ChannelBtn{border-image:url(:/images/images/hideChannel.png);}"; + } + else + { + strStyle = "#ChannelBtn{border-image:url(:/images/images/showChannel.png);}"; + } + ui->ChannelBtn->setStyleSheet(strStyle); +} diff --git a/ChaosDataPlayer/Child3dFrom.h b/ChaosDataPlayer/Child3dFrom.h new file mode 100644 index 0000000..9867f31 --- /dev/null +++ b/ChaosDataPlayer/Child3dFrom.h @@ -0,0 +1,33 @@ +#ifndef CHILD3DFROM_H +#define CHILD3DFROM_H + +#include +#include"mylineplot3d.h" + +namespace Ui { +class Child3DFrom; +} + +class Child3DFrom : public QWidget +{ + Q_OBJECT + +public: + explicit Child3DFrom(QWidget *parent = nullptr); + ~Child3DFrom(); + +public slots: + + void ChannelBtnSlot(); +private: + Ui::Child3DFrom *ui; + + mylineplot3d *myL3d; + Qwt3D::Line3D * mypL3d_1; + + double x; + double y; + double z; +}; + +#endif // CHILD3DFROM_H diff --git a/ChaosDataPlayer/Child3dFrom.ui b/ChaosDataPlayer/Child3dFrom.ui new file mode 100644 index 0000000..2c88d0b --- /dev/null +++ b/ChaosDataPlayer/Child3dFrom.ui @@ -0,0 +1,793 @@ + + + Child3DFrom + + + + 0 + 0 + 1014 + 481 + + + + Form + + + #outBtn{border-image:url(:/images/images/imgModelAction/657.png);} +#returnBtn{border-image:url(:/images/images/imgModelAction/344.png);} + +#label_title{color: #aac3cf;} + +#tableWidget +{ + background:transparent; + border-top: 2px solid #50707f; + +} + +#tableWidget::item +{ + height: 24px; + border-width: 1; +} +#tableWidget::item:hover +{ + border: none; +} +#tableWidget::item:selected +{ + border: none; + color:#ffa405; +} + +#ChannelBtn{border-image:url(:/images/images/showChannel.png);} + +#line_3{border-image:url(:/images/images/line.png);} +#line_4{border-image:url(:/images/images/line.png);} + +#zoomBtn_X { border-image:url(:/images/images/imgModelAction/axisX.png) 5; } +#zoomBtn_X:hover { border-image:url(:/images/images/imgModelAction/axisX-h.png) 5; } +#zoomBtn_X:pressed {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } +#zoomBtn_X:checked {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } + +#zoomBtn_Y { border-image:url(:/images/images/imgModelAction/axisY.png) 5; } +#zoomBtn_Y:hover { border-image:url(:/images/images/imgModelAction/axisY-h.png) 5; } +#zoomBtn_Y:pressed {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } +#zoomBtn_Y:checked {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } + +#zoomBtn_hand { border-image:url(:/images/images/imgModelAction/hand.png) 5; } +#zoomBtn_hand:hover { border-image:url(:/images/images/imgModelAction/hand-h.png) 5; } +#zoomBtn_hand:pressed {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } +#zoomBtn_hand:checked {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } + + +#measureBtn { border-image:url(:/images/images/imgModelAction/measure.png) 5; } +#measureBtn:hover { border-image:url(:/images/images/imgModelAction/measure-h.png) 5; } +#measureBtn:pressed {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } +#measureBtn:checked {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } + +#realTimeDataBtn { border-image:url(:/images/images/imgModelAction/realTime.png) 5; } +#realTimeDataBtn:hover { border-image:url(:/images/images/imgModelAction/realTime.png) 5; } +#realTimeDataBtn:pressed {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } +#realTimeDataBtn:checked {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } + +#temBtn { border-image:url(:/images/images/imgModelAction/HZ.png) 5; } +#temBtn:hover { border-image:url(:/images/images/imgModelAction/HZ-h.png) 5; } +#temBtn:pressed {border-image:url(:/images/images/imgModelAction/HZ-h.png) 5; } + +#temBtn_2 { border-image:url(:/images/images/imgModelAction/AC.png) 5; } +#temBtn_2:hover { border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } +#temBtn_2:pressed {border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } + +#temBtn_3 { border-image:url(:/images/images/imgModelAction/arf.png) 5; } +#temBtn_3:hover { border-image:url(:/images/images/imgModelAction/arf-h.png) 5; } +#temBtn_3:pressed {border-image:url(:/images/images/imgModelAction/arf-h.png) 5; } + +#temBtn_4 { border-image:url(:/images/images/imgModelAction/lvbo.png) 5; } +#temBtn_4:hover { border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; } +#temBtn_4:pressed {border-image:url(:/images/images/imgModelAction/lvbo-p.png) 5; } + +#temBtn_5 { border-image:url(:/images/images/imgModelAction/TDBC.png) 5; } +#temBtn_5:hover { border-image:url(:/images/images/imgModelAction/TDBC-h.png) 5; } +#temBtn_5:pressed {border-image:url(:/images/images/imgModelAction/TDBC-P.png) 5; } + +#temBtn_6 { border-image:url(:/images/images/imgModelAction/gb1.png) 5; } +#temBtn_6:hover { border-image:url(:/images/images/imgModelAction/gb1.png) 5; } +#temBtn_6:pressed {border-image:url(:/images/images/imgModelAction/gb1.png) 5; } + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 300 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 38 + + + + + 16777215 + 38 + + + + color: rgb(170, 195, 207); + + + TextLabel + + + + + + + + + + false + + + 2 + + + false + + + true + + + false + + + + + + + + + + + + 0 + + + 2 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 16 + 120 + + + + + 16 + 120 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 41 + + + + + 16777215 + 41 + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + true + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + true + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + true + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + true + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 2 + 28 + + + + + 2 + 28 + + + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 2 + 28 + + + + + 2 + 28 + + + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + true + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + #outBtn{border-image:url(:/images/images/imgModelAction/657.png);} +#returnBtn{border-image:url(:/images/images/imgModelAction/344.png);} + +#label_title{color: #aac3cf;} + +#tableWidget +{ + background:transparent; + border-top: 2px solid #50707f; + +} + +#tableWidget::item +{ + height: 24px; + border-width: 1; +} +#tableWidget::item:hover +{ + border: none; +} +#tableWidget::item:selected +{ + border: none; + color:#ffa405; +} + +#ChannelBtn{border-image:url(:/images/images/showChannel.png);} + +#line_3{border-image:url(:/images/images/line.png);} +#line_4{border-image:url(:/images/images/line.png);} + +#zoomBtn_X { border-image:url(:/images/images/imgModelAction/axisX.png) 5; } +#zoomBtn_X:hover { border-image:url(:/images/images/imgModelAction/axisX-h.png) 5; } +#zoomBtn_X:pressed {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } +#zoomBtn_X:checked {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } + +#zoomBtn_Y { border-image:url(:/images/images/imgModelAction/axisY.png) 5; } +#zoomBtn_Y:hover { border-image:url(:/images/images/imgModelAction/axisY-h.png) 5; } +#zoomBtn_Y:pressed {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } +#zoomBtn_Y:checked {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } + +#zoomBtn_hand { border-image:url(:/images/images/imgModelAction/hand.png) 5; } +#zoomBtn_hand:hover { border-image:url(:/images/images/imgModelAction/hand-h.png) 5; } +#zoomBtn_hand:pressed {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } +#zoomBtn_hand:checked {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } + + +#measureBtn { border-image:url(:/images/images/imgModelAction/measure.png) 5; } +#measureBtn:hover { border-image:url(:/images/images/imgModelAction/measure-h.png) 5; } +#measureBtn:pressed {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } +#measureBtn:checked {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } + +#realTimeDataBtn { border-image:url(:/images/images/imgModelAction/realTime.png) 5; } +#realTimeDataBtn:hover { border-image:url(:/images/images/imgModelAction/realTime.png) 5; } +#realTimeDataBtn:pressed {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } +#realTimeDataBtn:checked {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } + +#temBtn { border-image:url(:/images/images/imgModelAction/HZ.png) 5; } +#temBtn:hover { border-image:url(:/images/images/imgModelAction/HZ-h.png) 5; } +#temBtn:pressed {border-image:url(:/images/images/imgModelAction/HZ-h.png) 5; } + +#temBtn_2 { border-image:url(:/images/images/imgModelAction/AC.png) 5; } +#temBtn_2:hover { border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } +#temBtn_2:pressed {border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } + +#temBtn_3 { border-image:url(:/images/images/imgModelAction/arf.png) 5; } +#temBtn_3:hover { border-image:url(:/images/images/imgModelAction/arf-h.png) 5; } +#temBtn_3:pressed {border-image:url(:/images/images/imgModelAction/arf-h.png) 5; } + +#temBtn_4 { border-image:url(:/images/images/imgModelAction/lvbo.png) 5; } +#temBtn_4:hover { border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; } +#temBtn_4:pressed {border-image:url(:/images/images/imgModelAction/lvbo-p.png) 5; } + +#temBtn_5 { border-image:url(:/images/images/imgModelAction/TDBC.png) 5; } +#temBtn_5:hover { border-image:url(:/images/images/imgModelAction/TDBC-h.png) 5; } +#temBtn_5:pressed {border-image:url(:/images/images/imgModelAction/TDBC-P.png) 5; } + +#temBtn_6 { border-image:url(:/images/images/imgModelAction/gb1.png) 5; } +#temBtn_6:hover { border-image:url(:/images/images/imgModelAction/gb1.png) 5; } +#temBtn_6:pressed {border-image:url(:/images/images/imgModelAction/gb1.png) 5; } + + + + + + + + + + + + diff --git a/ChaosDataPlayer/ChildForm.cpp b/ChaosDataPlayer/ChildForm.cpp new file mode 100644 index 0000000..51bd014 --- /dev/null +++ b/ChaosDataPlayer/ChildForm.cpp @@ -0,0 +1,3252 @@ +#include "ChildForm.h" +#include "ui_ChildForm.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "LegendForm.h" +#include "secure.h" +#include +#include "portaudio.h" +#include +#include + +#define FRAMES_PER_BUFFER (1024) + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + +#define TABLE_SIZE (200) + + + + + +#define CHANNELID_ROLE (Qt::UserRole + 2) +#define CHANNELTYPE_ROLE (Qt::UserRole + 3) + +ChildForm::ChildForm(FormType iType,QString m_strName,DEVICE_INFO* DeviceInfo,QWidget *parent) : + BaseWgt(parent), + ui(new Ui::ChildForm), + m_pChartView(nullptr), + m_iFormType(iType), + m_bAttach(false), + m_pLegendForm(nullptr), + m_iRealTimer(0), + m_bDC(false), + //m_client(nullptr), + m_bRpm(false), + m_bIntegration(false), + m_bDifferentiation(false), + m_bDoubleIntegration(false), + m_bDoubleDifferentiation(false), + m_isconnect(false), + m_bRealTime(false), + m_isPause(false), + m_isStop(false) +{ + m_position = 0; + m_nStart = 0; + m_nEnd = 0; + ui->setupUi(m_pMainWgt); + SetFormType(iType); + setWindowTitle(m_strName); + + + + + connect(ui->Btn_Open, SIGNAL(clicked()), this, SIGNAL(OutSig())); + connect(ui->Btn_Close, SIGNAL(clicked()), this, SIGNAL(ReturnSig())); + +// connect(ui->zoomBtn_X, SIGNAL(clicked()), this, SLOT(ZoomBtnSlot_X())); +// connect(ui->zoomBtn_Y, SIGNAL(clicked()), this, SLOT(ZoomBtnSlot_Y())); +// connect(ui->Btn_Integration, SIGNAL(clicked()), this, SLOT(Integration())); +// connect(ui->zoomBtn_hand, SIGNAL(clicked()), this, SLOT(ZoomBtnSlot_Hand())); +// connect(ui->measureBtn, SIGNAL(clicked()), this, SLOT(MeasureBtnSlot())); + + connect(ui->ChannelBtn, SIGNAL(clicked()), this, SLOT(ChannelBtnSlot())); //打开通道选择 + connect(ui->zoomBtn_hand, SIGNAL(clicked()), this, SLOT(ZoomBtnSlot_Hand())); + connect(ui->Btn_Zoom, SIGNAL(clicked()), this, SLOT(Btn_ZoomSlot())); + connect(ui->Btn_setScales, SIGNAL(clicked()), this, SLOT(SetScales())); + connect(ui->temBtn_4, SIGNAL(clicked()), this, SLOT(SetFilter())); + connect(ui->Btn_AC_DC, SIGNAL(clicked()), this, SLOT(SetDC())); + connect(ui->realTimeDataBtn, SIGNAL(clicked()), this, SLOT(realTimeData())); + connect(ui->Btn_Sound, SIGNAL(clicked()), this, SLOT(OnPlayWaveSound())); + + + + + connect(ui->tableWidget, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(ItemChangedSlot(QTableWidgetItem *))); + connect(ui->tableWidget, SIGNAL(itemPressed(QTableWidgetItem *)),SLOT(ItemPressSlot(QTableWidgetItem *))); + + InitWidget(); + mqttclient = new MqttClient(this); + mqttclient->ConnectMQTT(DeviceInfo->DeviceIP); + m_DeviceInfo = DeviceInfo; + line = 0; + ui->ChannelWgt->setVisible(false); + ui->tableWidget->setColumnWidth(0, 260); + ui->tableWidget->setColumnWidth(1, 20); + ui->tableWidget->setSelectionMode(QAbstractItemView::MultiSelection); + + tracer = new QCPItemTracer(ui->widget); + tracer->setStyle(QCPItemTracer::tsCrosshair); + tracer->setPen(QPen(Qt::red)); + tracer->setBrush(Qt::red); + tracer->setSize(6); + tracer->setVisible(false); + tracer->setInterpolating(false); + + tracer2 = new QCPItemTracer(ui->widget); + tracer2->setStyle(QCPItemTracer::tsCircle); + tracer2->setPen(QPen(Qt::red)); + tracer2->setBrush(Qt::red); + tracer2->setSize(6); + tracer2->setVisible(false); + + + tracerLabel = new QCPItemText(ui->widget); + tracerLabel->setLayer("overlay"); + tracerLabel->setPen(QPen(Qt::black)); + tracerLabel->setBrush(Qt::white); + tracerLabel->setPadding(QMargins(2,2,2,2));//边界宽度 + tracerLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignLeft);//文字布局:顶、左对齐 + tracerLabel->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel->position->setCoords(0, 0); + + //下面这个语句很重要,它将游标说明锚固在tracer位置处,实现自动跟随 + //tracerLabel->position->setParentAnchor(tracer->position); + tracerLabel->setVisible(false); + + tracerLabel2 = new QCPItemText(ui->widget); + tracerLabel2->setLayer("overlay"); + tracerLabel2->setPen(QPen(Qt::black)); + tracerLabel2->setBrush(Qt::white); + tracerLabel2->setPadding(QMargins(2,2,2,2));//边界宽度 + tracerLabel2->setPositionAlignment(Qt::AlignHCenter | Qt::AlignTop); + tracerLabel2->setVisible(false); + + tracerLabel3 = new QCPItemText(ui->widget); + tracerLabel3->setLayer("overlay"); + tracerLabel3->setPen(QPen(Qt::black)); + tracerLabel3->setBrush(Qt::white); + tracerLabel3->setPadding(QMargins(2,2,2,2));//边界宽度 + tracerLabel3->setPositionAlignment(Qt::AlignTop | Qt::AlignLeft); + tracerLabel3->setVisible(false); + tracerLabel3->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel3->position->setCoords(0, 0.04); + + tracerLabel4 = new QCPItemText(ui->widget); + tracerLabel4->setLayer("overlay"); + tracerLabel4->setPen(QPen(Qt::black)); + tracerLabel4->setBrush(Qt::white); + tracerLabel4->setPadding(QMargins(2,2,2,2));//边界宽度 + tracerLabel4->setPositionAlignment(Qt::AlignTop | Qt::AlignLeft); + tracerLabel4->setVisible(false); + tracerLabel4->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel4->position->setCoords(0, 0.08); + + tracerLabel5 = new QCPItemText(ui->widget); + tracerLabel5->setLayer("overlay"); + tracerLabel5->setPen(QPen(Qt::black)); + tracerLabel5->setBrush(Qt::white); + tracerLabel5->setPadding(QMargins(2,2,2,2));//边界宽度 + tracerLabel5->setPositionAlignment(Qt::AlignTop | Qt::AlignLeft); + tracerLabel5->setVisible(false); + tracerLabel5->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel5->position->setCoords(0, 0.12); + + + //背景为黑色 + QLinearGradient plotGradient; + plotGradient.setColorAt(0, QColor(0, 0, 0)); + plotGradient.setColorAt(1, QColor(0, 0, 0)); + ui->widget->setBackground(plotGradient); + //坐标轴为白色 + ui->widget->xAxis->setBasePen(QPen(Qt::white, 1)); + ui->widget->yAxis->setBasePen(QPen(Qt::white, 1)); + ui->widget->yAxis2->setBasePen(QPen(Qt::white, 1)); + + //坐标轴的提示信息为白色 + ui->widget->xAxis->setTickLabelColor(Qt::white); + ui->widget->yAxis->setTickLabelColor(Qt::white); + ui->widget->yAxis2->setTickLabelColor(Qt::white); + //ui->widget->yAxis->setTickLabelRotation(40);//设置刻度显示方向位倾斜向下 + + ui->widget->xAxis->setLabelColor(Qt::white); + ui->widget->yAxis->setLabelColor(Qt::white); + ui->widget->yAxis2->setLabelColor(Qt::white); + + ui->widget->yAxis2->setVisible(false); + ui->widget->yAxis2->setTickLabels(true); + + yAxis3 = ui->widget->axisRect()->addAxis(QCPAxis::atRight); + yAxis3->setTickLabelColor(Qt::white); + yAxis3->setBasePen(QPen(Qt::white, 1)); + yAxis3->setLabelColor(Qt::white); + yAxis3->setTickLabels(true); + yAxis3->setVisible(false); + + axes.append(ui->widget->yAxis); + axes.append(ui->widget->yAxis2); + axes.append(yAxis3); + + //ui->widget->setInteractions(QCP::iSelectPlottables); + //鼠标点击 + // connect(ui->widget, SIGNAL(plottableClick(QCPAbstractPlottable*, int, QMouseEvent*)), this, SLOT(OnPlotClick(QCPAbstractPlottable*, int, QMouseEvent*))); + + if(iType == OrbitPlot){ + ui->widget->setOpenGl(true); + }else{ + //dismove = connect(ui->widget, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveEvent(QMouseEvent*))); + disDoubleclick = connect(ui->widget, SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(mouseDoubleClickEvent(QMouseEvent*))); + + } + //disPress = connect(ui->widget, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheelEvent(QWheelEvent*))); + qDebug() <<"Is start opengl?=" << ui->widget->openGl(); +// ui->widget->setAttribute(Qt::WA_StyledBackground,true); +// ui->widget->setStyleSheet("background-color: rgb(0,0, 0)");. + InitDisPaly(); + + + +} + +ChildForm::~ChildForm() +{ + free(tracer); + free(tracer2); + free(tracerLabel); + free(tracerLabel2); + free(tracerLabel3); + free(tracerLabel4); + free(tracerLabel5); + InitDisPaly(); + delete ui; +} +void ChildForm::InitDisPaly() +{ +// QMap>::Iterator iter = mapWaveDisplayData.begin(); +// for(iter = mapWaveDisplayData.begin();iter !=mapWaveDisplayData.end();iter++){ +// for (int i = 0;iter.value().size() ;i ++ ) { +// QVector temVec = iter.value(); +// for (int j = 0; j < temVec.size() ;j++ ) { +// QVector().swap(temVec[i].Key); +// QVector().swap(temVec[i].wavedata); +// } +// QVector().swap(iter.value()); +// } + +// mapWaveDisplayData.erase(iter); +// } + + + + /* QMap>::Iterator iterWave = mapWaveData.begin(); + for(iterWave = mapWaveData.begin();iterWave !=mapWaveData.end();iterWave++){ + for (int i = 0;iterWave.value().size() ;i ++ ) { + QVector temVec = iterWave.value(); + for (int j = 0; j < temVec.size() ;j++ ) { + QVector().swap(temVec[i].waveData); + } + QVector().swap(iterWave.value()); + } + mapWaveData.erase(iterWave); + }*/ +} + +void ChildForm::InitRpmDisPaly() +{ + QMap::Iterator iterDC = mapWaveDisplayData_RPM.begin(); + for(iterDC = mapWaveDisplayData_RPM.begin();iterDC != mapWaveDisplayData_RPM.end();iterDC++){ + mapWaveDisplayData_RPM.erase(iterDC); + } + m_bRpm = false; +} + +void ChildForm::InitWidget() +{ + QMenu *ZoomMenu = new QMenu(); + ZoomMenu->setWindowFlags(ZoomMenu->windowFlags() | Qt::FramelessWindowHint); + QAction *Zoom_xy = new QAction(ZoomMenu); + QAction * Zoom_x= new QAction(ZoomMenu); + QAction *Zoom_y = new QAction(ZoomMenu); + + ZoomMenu->addAction(Zoom_xy); + ZoomMenu->addAction(Zoom_x); + ZoomMenu->addAction(Zoom_y); + + Zoom_xy->setIcon(QIcon(":/images/images/imgModelAction/Zoom_xy.png")); + Zoom_x->setIcon(QIcon(":/images/images/imgModelAction/axisX.png")); + Zoom_y->setIcon(QIcon(":/images/images/imgModelAction/axisY.png")); + + Zoom_xy->setText(tr(" 自动缩放XY")); + Zoom_x->setText(tr(" 自动缩放X")); + Zoom_y->setText(tr(" 自动缩放Y")); + ui->Btn_ZoomMenu->setMenu(ZoomMenu); + + QMenu *HzMenu = new QMenu(); + HzMenu->setWindowFlags(HzMenu->windowFlags() | Qt::FramelessWindowHint); + Hz = new QAction(HzMenu); + Ord= new QAction(HzMenu); + Rad = new QAction(HzMenu); + + HzMenu->addAction(Rad); + HzMenu->addAction(Hz); + HzMenu->addAction(Ord); + + + Hz->setIcon(QIcon(":/images/images/imgModelAction/HZ.png")); + Ord->setIcon(QIcon(":/images/images/imgModelAction/Ord.png")); + Rad->setIcon(QIcon(":/images/images/imgModelAction/rpm.png")); + Rad->setText(tr(" Rpm")); + Hz->setText(tr(" Hz")); + Ord->setText(tr(" Ord")); + ui->Btn_Hz->setMenu(HzMenu); + + differentiationMenu = new QMenu(); + differentiationMenu->setWindowFlags(differentiationMenu->windowFlags() | Qt::FramelessWindowHint); + Integration = new QAction(differentiationMenu); + doubleIntegration = new QAction(differentiationMenu); + differentiation = new QAction(differentiationMenu); + doubleDifferentiation= new QAction(differentiationMenu); + + + differentiationMenu->addAction(Integration); + differentiationMenu->addAction(doubleIntegration); + differentiationMenu->addAction(differentiation); + differentiationMenu->addAction(doubleDifferentiation); + + Integration->setIcon(QIcon(":/images/images/imgModelAction/Integration.png")); + doubleIntegration->setIcon(QIcon(":/images/images/imgModelAction/doubleIntegration.png")); + differentiation->setIcon(QIcon(":/images/images/imgModelAction/arf.png")); + doubleDifferentiation->setIcon(QIcon(":/images/images/imgModelAction/doublearf.png")); + Integration->setText(tr(" 积分")); + doubleIntegration->setText(tr(" 二次积分")); + differentiation->setText(tr(" 微分")); + doubleDifferentiation->setText(tr(" 二次微分")); + ui->Btn_differentiation->setMenu(differentiationMenu); + + + connect(Integration, SIGNAL(triggered()), this, SLOT(IntegrationSlot())); + connect(doubleIntegration, SIGNAL(triggered()), this, SLOT(DoubleIntegrationSlot())); + connect(differentiation, SIGNAL(triggered()), this, SLOT(DifferentiationSlot())); + connect(doubleDifferentiation, SIGNAL(triggered()), this, SLOT(DoubleDifferentiationSlot())); + + connect(Zoom_xy, SIGNAL(triggered()), this, SLOT(ZoomBtnSlot_XY())); + connect(Zoom_x, SIGNAL(triggered()), this, SLOT(ZoomBtnSlot_X())); + connect(Zoom_y, SIGNAL(triggered()), this, SLOT(ZoomBtnSlot_Y())); + connect(Rad, SIGNAL(triggered()), this, SLOT(ToRpm())); + + QMenu *ScaleMenu = new QMenu(); + ScaleMenu->setWindowFlags(ScaleMenu->windowFlags() | Qt::FramelessWindowHint); + QAction *Scale_X = new QAction(ScaleMenu); + QAction *ScaleMenu_Y = new QAction(ScaleMenu); + QAction *ScaleMenu_XY = new QAction(ScaleMenu); + QAction *ScaleMenu_Box = new QAction(ScaleMenu); + + ScaleMenu->addAction(Scale_X); + ScaleMenu->addAction(ScaleMenu_Y); + ScaleMenu->addAction(ScaleMenu_XY); + ScaleMenu->addAction(ScaleMenu_Box); + + Scale_X->setIcon(QIcon(":/images/images/imgModelAction/Zoom_X.png")); + ScaleMenu_Y->setIcon(QIcon(":/images/images/imgModelAction/Zoom_Y.png")); + ScaleMenu_XY->setIcon(QIcon(":/images/images/imgModelAction/Zoom-XY.png")); + ScaleMenu_Box->setIcon(QIcon(":/images/images/imgModelAction/Zoom_Box.png")); + Scale_X->setText(tr(" 放大X")); + ScaleMenu_Y->setText(tr(" 放大Y")); + ScaleMenu_XY->setText(tr(" 放大XY")); + ScaleMenu_Box->setText(tr(" 框选放大")); + ui->Btn_Zoom->setMenu(ScaleMenu); + + connect(Scale_X, SIGNAL(triggered()), this, SLOT(ScalesX())); + connect(ScaleMenu_Y, SIGNAL(triggered()), this, SLOT(ScalesY())); + connect(ScaleMenu_XY, SIGNAL(triggered()), this, SLOT(ScalesXY())); + connect(ScaleMenu_Box, SIGNAL(triggered()), this, SLOT(ScalesBox())); + + + QMenu *CursorMenu = new QMenu(); + CursorMenu->setWindowFlags(CursorMenu->windowFlags() | Qt::FramelessWindowHint); + QAction *Cursor = new QAction(CursorMenu); + QAction *biandai = new QAction(CursorMenu); + QAction *xiebo = new QAction(CursorMenu); + QAction *fengzhi = new QAction(CursorMenu); + + CursorMenu->addAction(Cursor); + CursorMenu->addAction(biandai); + CursorMenu->addAction(xiebo); + CursorMenu->addAction(fengzhi); + + Cursor->setIcon(QIcon(":/images/images/imgModelAction/Cursor.png")); + biandai->setIcon(QIcon(":/images/images/imgModelAction/biandai.png")); + xiebo->setIcon(QIcon(":/images/images/imgModelAction/xiebo.png")); + fengzhi->setIcon(QIcon(":/images/images/imgModelAction/fengzhi.png")); + Cursor->setText(tr(" 光标")); + biandai->setText(tr(" 边带光标")); + xiebo->setText(tr(" 谐波光标")); + fengzhi->setText(tr(" 峰值光标")); + biandai->setEnabled(false); + xiebo->setEnabled(false); + fengzhi->setEnabled(false); + ui->Btn_Cursor->setMenu(CursorMenu); + + connect(Cursor, SIGNAL(triggered()), this, SLOT(Cursor())); + + ui->Btn_ZoomMenu->setStyleSheet("QPushButton::menu-indicator{image:none;}"); + ui->Btn_Zoom->setStyleSheet("QPushButton::menu-indicator{image:none;}"); + ui->Btn_Cursor->setStyleSheet("QPushButton::menu-indicator{image:none;}"); + + if(m_iFormType == EnvChartPlot){ + ui->temBtn_4->setStyleSheet(" QPushButton{ border-image:url(:/images/images/imgModelAction/lvbo.png) 5; }\ + QPushButton:hover{ border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; }\ + QPushButton:pressed{border-image:url(:/images/images/imgModelAction/lvbo-p.png) 5; }\ + QPushButton:checked{border-image:url(:/images/images/imgModelAction/lvbo.png) 5; } " ); + + ui->temBtn_4->setEnabled(true); + }else if (m_iFormType == TimeDomainPlot) { + ui->Btn_differentiation->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgModelAction/arf.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgModelAction/arf-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgModelAction/arf-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgModelAction/arf.png) 1; }\ + QPushButton::menu-indicator{image:none;}"); + + ui->Btn_AC_DC->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgModelAction/AC-p.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgModelAction/AC-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgModelAction/AC.png) 5; }\ + QPushButton:checked {border-image:url(:/images/images/imgModelAction/DC.png) 5; }"); + + ui->Btn_Hz->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgModelAction/HZ.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgModelAction/HZ-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgModelAction/hz-2.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgModelAction/HZ.png) 1; }"); + + ui->Btn_Sound->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgModelAction/Sound.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgModelAction/Sound-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgModelAction/Sound-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgModelAction/Sound-p.png) 1; }"); + + ui->temBtn_4->setStyleSheet(" QPushButton{ border-image:url(:/images/images/imgModelAction/lvbo.png) 5; }\ + QPushButton:hover{ border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; }\ + QPushButton:pressed{border-image:url(:/images/images/imgModelAction/lvbo-p.png) 5; }\ + QPushButton:checked{border-image:url(:/images/images/imgModelAction/lvbo.png) 5; } " ); + + ui->temBtn_4->setEnabled(true); + + ui->Btn_AC_DC->setEnabled(true); + ui->Btn_Sound->setEnabled(true); + ui->Btn_differentiation->setEnabled(true); + doubleIntegration->setEnabled(true); + differentiation->setEnabled(true); + doubleDifferentiation->setEnabled(true); + ui->Btn_Hz->setEnabled(true); + Ord->setEnabled(false); + Hz->setEnabled(false); + Rad->setEnabled(false); + }else if(m_iFormType == FrequencyDomainPlot){ + ui->Btn_differentiation->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgModelAction/arf.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgModelAction/arf-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgModelAction/arf-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgModelAction/arf.png) 1; }\ + QPushButton::menu-indicator{image:none;}"); + ui->temBtn_4->setStyleSheet(" QPushButton{ border-image:url(:/images/images/imgModelAction/lvbo.png) 5; }\ + QPushButton:hover{ border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; }\ + QPushButton:pressed{border-image:url(:/images/images/imgModelAction/lvbo-p.png) 5; }\ + QPushButton:checked{border-image:url(:/images/images/imgModelAction/lvbo.png) 5; } " ); + + ui->temBtn_4->setEnabled(true); + + ui->Btn_differentiation->setEnabled(true); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(false); + doubleDifferentiation->setEnabled(false); + }else if(m_iFormType == ShaftCenterline /*|| m_iFormType == BodePlot*/ || m_iFormType == PolarPlot || m_iFormType == OrbitPlot + || m_iFormType ==WaterFallPlot){ + Cursor->setEnabled(false); + } + +} + +void ChildForm::SetWaveData(QString strID, QVector& waveData) +{ + +} +QCPGraph* ChildForm::MultiyAxis(QString strID,QString sensorType,QString sensorEngineeringUnit) +{ + QCPGraph* graph = NULL; + QMap mapGraph; + + if(mapMultiGraph.size() < 3 || (mapMultiGraph.size() == 3 && mapMultiGraph.contains(sensorType))){ + + if(!mapMultiGraph.contains(sensorType)){ + + qDebug() << "contains" << endl; + if(mapMultiGraph.size() == 0){ + qDebug() << "mapMultiGraph1" << endl; + graph = ui->widget->addGraph(ui->widget->xAxis, axes[0]); + ui->widget->yAxis->setLabel(sensorType + "(" + sensorEngineeringUnit+")"); + axes[0]->setVisible(true); + mapGraph.insert(strID,axes[0]); + } + else if(mapMultiGraph.size() == 2 || mapMultiGraph.size() == 1){ + qDebug() << "mapMultiGraph3" << endl; + QList tmpaxes; + for(int i = 0 ; i < axes.size();i++){ + QMap>::iterator iter = mapMultiGraph.begin(); + for(;iter != mapMultiGraph.end();iter ++){ + + QMap::iterator iterGraph = iter.value().begin(); + if(axes[i] == iterGraph.value()){ + tmpaxes.push_back(axes[i]); + } + } + if(i == axes.size()-1){ + int eql1 = 0; + for(int k = 0 ; k < axes.size();k++){ + for(int j = 0; j < tmpaxes.size();j++){ + if(axes[k] == tmpaxes[j]){ + eql1 = 1; + break; + }else{ + eql1 = 0; + } + } + if(eql1 == 1){ + continue; + } + graph = ui->widget->addGraph(ui->widget->xAxis, axes[k]); + axes[k]->setLabel(sensorType + "(" + sensorEngineeringUnit+")"); + axes[k]->setVisible(true); + mapGraph.insert(strID,axes[k]); + break; + } + } + } + } + }else{ + qDebug() << "contains2" << endl; + QMap>::iterator iter = mapMultiGraph.begin(); + for(; iter != mapMultiGraph.end();iter++){ + if(iter.key() == sensorType){ + + QMap::iterator iterGraph = iter.value().begin(); + graph = ui->widget->addGraph(ui->widget->xAxis, iterGraph.value()); + mapGraph.insert(strID,iterGraph.value()); + qDebug() << "strID1" << strID << endl; + } + } + } + + + QMap>::iterator iter = mapMultiGraph.begin(); + for(; iter != mapMultiGraph.end();iter++){ + if(iter.key() == sensorType){ + QMap::iterator iterGraph = iter.value().begin(); + for(;iterGraph != iter.value().end();iterGraph ++){ + mapGraph.insert(iterGraph.key(),iterGraph.value()); + qDebug() << "strID2" << iterGraph.key() << endl; + } + } + } + mapMultiGraph.insert(sensorType,mapGraph); + waveGraph.insert(strID,graph); + return graph; + } + else{ + + qDebug() << "multiGraph" << endl; + + m_mapChannelIDtoLabel[strID]->setSelected(false); + m_mapChannelIDtoLabel[strID]->setCheckState(Qt::Unchecked); + return NULL; + } +} +void ChildForm::SecondData(const QString& strID,WAVE_DATA& waveData,WAVE_DISPALYDATA& waveShowData) +{ + double f = 0; + double gap = (double)1/(double)waveData.SamleRate; + if(m_iFormType == TimeDomainPlot)//时域图 + { + f = 0.0; + if(m_bRealTime){ + gap = (double)1/(double)waveData.SamleRateRealTime; + double sum = std::accumulate(std::begin(waveData.waveDataRealTime), std::end(waveData.waveDataRealTime), 0.0); + float size = waveData.SamleRateRealTime; + double mean = sum/size; + for(int j = 0 ; j < waveData.SamleRateRealTime;j++){ + + waveShowData.wavedata.push_back(waveData.waveDataRealTime.at(j)-mean); + f += gap; + waveShowData.Key.push_back(f); + waveShowData.wavedata_DC.push_back(waveData.waveDataRealTime.at(j)); + } + qDebug() << "waveShowData.wavedata_DC" << waveShowData.wavedata_DC.size()<< endl; + }else{ + QVector vecOutData; + for(int j = 0 ; j < waveData.wavesize;j++){ + waveShowData.wavedata.push_back(waveData.waveData.at(j)-waveData.mean); + f += gap; + waveShowData.Key.push_back(f); + waveShowData.wavedata_DC.push_back(waveData.waveData.at(j)); + } + if(m_nStart > 0 && m_nEnd > 0){ + double FrequencyBands[2] = { (double)m_nStart/waveData.SamleRate*2, (double)m_nEnd/waveData.SamleRate*2 }; + pCalculation->ButterWorth(waveShowData.wavedata,FrequencyBands,vecOutData); + QVector().swap(waveShowData.wavedata); + waveShowData.wavedata = vecOutData; + } + } + + waveShowData.linColor = waveData.linColor; + waveShowData.channelType = waveData.sensorType; + waveShowData.sensorEngineeringUnit = waveData.sensorEngineeringUnit; + waveShowData.SamleRate = waveData.SamleRate; + waveShowData.mean = waveData.mean; + waveShowData.channleName = waveData.channelName; + + waveShowData.iTrigger = waveData.iTrigger; + waveShowData.iKeyCount = waveData.iKeyCount; + waveShowData.iTriggerValue = waveData.iTriggerValue; + waveShowData.iHysteresis = waveData.iHysteresis; + ui->widget->xAxis->setLabel("Time(s)"); + }else if(m_iFormType == FrequencyDomainPlot){ + WAVE_DISPALYDATA WaveDisplay; + QVector vecFFTSpecData; + QVector vecData; + for(int j = 0; j < waveData.wavesize;j++){ + float fData = waveData.waveData.at(j)-waveData.mean; + vecData.push_back(fData); + } + + QVector vecOutData; + if(m_nStart > 0 && m_nEnd > 0){ + double FrequencyBands[2] = { (double)m_nStart/waveData.SamleRate*2, (double)m_nEnd/waveData.SamleRate*2 }; + pCalculation->ButterWorth(vecData,FrequencyBands,vecOutData); + QVector().swap(vecData); + vecData = vecOutData; + } + + pCalculation->FFTSpec(vecData,vecFFTSpecData);//每一秒的FFT + qDebug() << vecData.size() <widget->xAxis->setLabel("Frequency(Hz)"); + }else if(m_iFormType == EnvChartPlot){ + + QVector vecEnvSpecData; + QVector vecData; + for(int j = 0; j < waveData.wavesize;j++){ + float fData = waveData.waveData.at(j)-waveData.mean; + vecData.push_back(fData); + } + if(m_nStart == 0 || m_nEnd == 0){ + pCalculation->envSpec(vecData,vecEnvSpecData,1000,10000); + }else{ + pCalculation->envSpec(vecData,vecEnvSpecData,m_nStart,m_nEnd); + } + for(int jj = 0 ; jj < vecEnvSpecData.size();jj++){ + waveShowData.Key.push_back(jj); + } + waveShowData.wavedataEnv = vecEnvSpecData; + waveShowData.wavedata = vecData; + waveShowData.linColor = waveData.linColor; + //wavetempData.push_back(vecEnvSpecData); + waveShowData.channelType = waveData.sensorType; + waveShowData.sensorEngineeringUnit = waveData.sensorEngineeringUnit; + ui->widget->xAxis->setLabel("Frequency(Hz)"); + } + + + + if(mapWaveDisplayData.contains(strID)){ + + mapWaveDisplayData[strID] = waveShowData; + }else{ + mapWaveDisplayData.insert(strID,waveShowData); + } +} +void ChildForm::UpdateDiffMenu() +{ + if(mapMultiGraph.contains("VELOCITY") && mapMultiGraph.contains("ACCELEROMETER")){ + Integration->setEnabled(true); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(false); + doubleDifferentiation->setEnabled(false); + }else if(mapMultiGraph.contains("VELOCITY") && mapMultiGraph.contains("ACCELEROMETER")){ + Integration->setEnabled(false); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(true); + doubleDifferentiation->setEnabled(false); + }else if(mapMultiGraph.contains("ACCELEROMETER") && + !(mapMultiGraph.contains("THRUST") || mapMultiGraph.contains("PROXIMETER")) + && !(mapMultiGraph.contains("VELOCITY")) && !(mapMultiGraph.contains("MICROPHONE")) + && !(mapMultiGraph.contains("SLOW_CURRENT")) && !(mapMultiGraph.contains("FAST_VOLTAGE")) + && !(mapMultiGraph.contains("TACHOMETER"))){ + Integration->setEnabled(true); + doubleIntegration->setEnabled(true); + differentiation->setEnabled(false); + doubleDifferentiation->setEnabled(false); + }else if(mapMultiGraph.contains("VELOCITY") && + !(mapMultiGraph.contains("ACCELEROMETER")) + && !(mapMultiGraph.contains("ACCELEROMETER")) + && !((mapMultiGraph.contains("THRUST")) || mapMultiGraph.contains("PROXIMETER")) + && !(mapMultiGraph.contains("MICROPHONE")) + && !(mapMultiGraph.contains("SLOW_CURRENT")) && !(mapMultiGraph.contains("FAST_VOLTAGE")) + && !(mapMultiGraph.contains("TACHOMETER"))){ + Integration->setEnabled(true); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(true); + doubleDifferentiation->setEnabled(false); + }else if((mapMultiGraph.contains("THRUST") || mapMultiGraph.contains("PROXIMETER")) && + !(mapMultiGraph.contains("ACCELEROMETER")) && !(mapMultiGraph.contains("VELOCITY")) + && !(mapMultiGraph.contains("MICROPHONE")) + && !(mapMultiGraph.contains("SLOW_CURRENT")) && !(mapMultiGraph.contains("FAST_VOLTAGE")) + && !(mapMultiGraph.contains("TACHOMETER"))){ + Integration->setEnabled(false); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(true); + doubleDifferentiation->setEnabled(true); + }else{ + Integration->setEnabled(false); + doubleIntegration->setEnabled(false); + differentiation->setEnabled(false); + doubleDifferentiation->setEnabled(false); + } + +} +void ChildForm::AddSeries(QString strID, QVector& waveData) +{ + //InitDisPaly(); + qDebug() << "AddSeries"<setEnabled(true); + }else{ + Rad->setEnabled(false); + } + + + mapWaveDisplayData.insert(strID,waveShowData); + + QCPGraph* graph = MultiyAxis(strID,waveShowData.channelType,waveShowData.sensorEngineeringUnit); + if(graph == NULL) + return; + + if(waveData[0].sensorType == "ACCELEROMETER" || waveData[0].sensorType == "VELOCITY" || + waveData[0].sensorType == "MICROPHONE"){ + + ui->Btn_AC_DC->setEnabled(false); + }else{ + ui->Btn_AC_DC->setEnabled(true); + } + + if(!m_bDC) + { + ui->widget->graph(line)->setData(waveShowData.Key, waveShowData.wavedata); + }else{ + ui->widget->graph(line)->setData(waveShowData.Key, waveShowData.wavedata_DC); + } + ui->widget->graph(line)->setName(waveData[0].channelName); + ui->widget->xAxis->setRange(0, 1); + UpdateDiffMenu(); + + }else if(m_iFormType == TrendChartPlot){//趋势图 + int Time = waveData.size(); + //qDebug() << "Time" << Time << endl; + QVector().swap(x); + QVector wavetempTrendData; + for(int i = 0; i < Time;i++){//平方和除以点数再开根 + +// float Sum = 0.0; +// for(int j = 0; j < waveData[i].SamleRate;j++){ +// float fData = waveData[i].waveData.at(j)-waveData[i].mean; +// fData = fData*fData; +// Sum += fData; +// } +// float rms = sqrt(Sum/waveData[i].SamleRate); //加速度有效值 + x.push_back(i); + //wavetempTrendData.push_back(rms); + } + ui->widget->xAxis->setRange(0, Time); + ui->widget->xAxis->setLabel("Time(s)"); + waveTrendData.insert(strID,wavetempTrendData); + QCPGraph* graph = MultiyAxis(strID,waveData[0].sensorType,waveData[0].sensorEngineeringUnit); + if(graph == NULL) + return; + + if(waveData[0].sensorType == "TACHOMETER"){ + ui->widget->graph(line)->setData(x, waveData[0].SpeedProfileSpeed); + }else{ + ui->widget->graph(line)->setData(x, waveData[0].RMSValue); + } + ui->widget->graph(line)->setName(waveData[0].channelName); + ui->widget->replot(QCustomPlot::rpQueuedReplot);//刷新图表 + + }else if(m_iFormType == FrequencyDomainPlot){//频域图 + + if(waveData[0].sensorType == "ACCELEROMETER" || waveData[0].sensorType == "VELOCITY"){ + Integration->setEnabled(true); + }else{ + Integration->setEnabled(false); + } + WAVE_DISPALYDATA vecWaveDisplay; + SecondData( strID,waveData[0], vecWaveDisplay); + + ui->widget->xAxis->setRange(0, 1000); + QCPGraph* graph = MultiyAxis(strID,vecWaveDisplay.channelType,vecWaveDisplay.sensorEngineeringUnit); + if(graph == NULL) + return; + ui->widget->xAxis->setLabel("Frequency(Hz)"); + ui->widget->graph(line)->setData(vecWaveDisplay.Key, vecWaveDisplay.wavedata); + ui->widget->graph(line)->setName(waveData[0].channelName); + + }else if(m_iFormType == EnvChartPlot){//包络图 + + QVector> wavetempData; + WAVE_DISPALYDATA vecWaveDisplay; + SecondData( strID,waveData[0], vecWaveDisplay); + + QCPGraph* graph = MultiyAxis(strID,vecWaveDisplay.channelType,vecWaveDisplay.sensorEngineeringUnit); + if(graph == NULL) + return; + ui->widget->xAxis->setLabel("Frequency(Hz)"); + ui->widget->xAxis->setRange(0, 1000); + qDebug() << "line" <widget->graph(line)->setData(vecWaveDisplay.Key, vecWaveDisplay.wavedataEnv); + ui->widget->graph(line)->setName(waveData[0].channelName); + + }else if(m_iFormType == WaterFallPlot){//瀑布图 + int k = 0; + //取消其他通道 + foreach (auto ID, listChannelID){ + if(ID != strID){ + m_mapChannelIDtoLabel[ID]->setCheckState(Qt::Unchecked); + m_mapChannelIDtoLabel[ID]->setSelected(false); + } + } + ui->widget->clearGraphs(); + line = 0; + + for(int i = 0; i < waveData.size();i++){ + QVector vecFFTSpecData; + QVector vecData; + QVector x1,y1; + for(int j = 0; j < waveData[i].waveData.size();j++){ + float fData = waveData[i].waveData.at(j)-waveData[i].mean; + vecData.push_back(fData); + } + pCalculation->FFTSpec(vecData,vecFFTSpecData); + for(k = 0; k < vecFFTSpecData.size();k++){ + x1.push_back(k+50*line); + y1.push_back(vecFFTSpecData.at(k)+0.1*line); + } + + ui->widget->addGraph(); + QPen pen; + pen.setColor(waveData.at(0).linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(line)->setData(x1, y1); + ui->widget->graph(line)->setPen(pen); + + line ++; + } + ui->widget->graph(0)->rescaleAxes(); + + ui->widget->xAxis->setRange(0, waveData[0].SamleRate/2); + ui->widget->xAxis->setLabel("Frequency(Hz)"); + ui->widget->yAxis->setLabel(waveData[0].sensorType + "(" + waveData[0].sensorEngineeringUnit+")"); + + } + if(m_iFormType != WaterFallPlot){//设置通道颜色 + ui->widget->graph(line)->rescaleValueAxis(); + QPen pen; + pen.setColor(waveData.at(line).linColor); + + + pen.setStyle(Qt::SolidLine); + if(m_iFormType == TrendChartPlot){ + pen.setWidth(2); + }else{ + pen.setWidth(1); + } + ui->widget->graph(line)->setPen(pen); + line++; + } + ui->widget->replot(); + ZoomBtnSlot_XY(); + +} +void ChildForm::UpdateEnvSerises(QString Start,QString End) +{ + + ui->widget->clearGraphs(); + InitDisPaly(); + if(Start.toInt() < 10 || End.toInt() > 131072){ + MyMsgBox(QMessageBox::Warning,"警告","请输入正确信息!"); + return; + } + + m_nStart = Start.toInt(); + m_nEnd = End.toInt(); + handlePlayWave(m_position,0); + +// QVector vecWaveDisplay; +// WAVE_DISPALYDATA WaveDisplay; +// QMap::Iterator iter = mapWaveDisplayData.begin(); +// qDebug() << "listChannelID" << listChannelID.size() < vecEnvSpecData; +// QVector vecData; +// for(int j = 0; j < iter.value().wavedata.size();j++){ +// float fData = iter.value().wavedata.at(j); +// vecData.push_back(fData); +// } +// pCalculation->envSpec(vecData,vecEnvSpecData,Start.toInt(),End.toInt()); +// qDebug() << "vecEnvSpecData" << vecEnvSpecData.size() <widget->addGraph(); +// waveGraph.insert(listChannelID.at(ii),graph); +// qDebug() << "wavedataEnv" << WaveDisplay.wavedataEnv.size() <widget->graph(line)->setData(WaveDisplay.Key, WaveDisplay.wavedataEnv); +// ui->widget->graph(line)->rescaleValueAxis(true); +// ui->widget->graph(line)->setPen(pen); +// ui->widget->replot(QCustomPlot::rpImmediateRefresh); +// line ++ ; +// } +// } +// } +} +void ChildForm::handlePlayWave(double position,double size ) + { + if(m_iFormType == WaterFallPlot){ + int graphCount = ui->widget->graphCount(); + if(graphCount < 1) + return; + QPen pen; + pen.setColor(QColor(255,140,0)); + pen.setStyle(Qt::SolidLine); + pen.setWidth(2); + ui->widget->graph(position)->setPen(pen); + ui->widget->replot(); + for(int i = 0; i < graphCount;i++){ + if( i != position){ + QPen pen; + pen.setColor(childWave[0].linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(position)->setPen(pen); + } + } + }else if(m_iFormType == TrendChartPlot){ + + }else + { + int graphCount = ui->widget->clearGraphs(); + } + if(m_iFormType != TrendChartPlot) + QMap().swap(waveGraph); + m_position = position; + //使键轴范围与数据一起滚动: + if(m_iFormType == FrequencyDomainPlot || + m_iFormType == EnvChartPlot || + m_iFormType == TimeDomainPlot){ + int xRange = 0; + QCPGraph* graph = NULL; + for (int i = 0; i < listChannelID.size(); ++i){ + WAVE_DISPALYDATA waveShowData; + QMap>::Iterator iterWaveData = mapWaveData.begin(); + for(;iterWaveData != mapWaveData.end();iterWaveData++) + { + if(listChannelID.at(i) == iterWaveData.key()){ + QMap>::Iterator iterMultiAxis = mapMultiGraph.begin(); + for(;iterMultiAxis != mapMultiGraph.end();iterMultiAxis++){ + QMap::Iterator iterAxis = iterMultiAxis.value().begin(); + for(;iterAxis != iterMultiAxis.value().end();iterAxis++){ + if(iterAxis.key() == listChannelID.at(i)){ + qDebug() << iterAxis.key() << endl; + SecondData(listChannelID.at(i),iterWaveData.value()[position],waveShowData); + graph = ui->widget->addGraph(ui->widget->xAxis,iterAxis.value()); + iterAxis.value()->setLabel(waveShowData.channelType + "(" + waveShowData.sensorEngineeringUnit+")"); + } + } + } + } + } + if(m_bRpm){ + CalculateRPM(); + } + if(m_bIntegration || m_bDoubleIntegration){ + if(m_bIntegration) + CalculateIntegration(false); + else if(m_bDoubleIntegration) + CalculateIntegration(true); + } + if(m_bDifferentiation || m_bDoubleDifferentiation){ + if(m_bDifferentiation) + CalculateDifferentiation(false); + else if(m_bDoubleDifferentiation) + CalculateDifferentiation(true); + }else + { + if(m_bDC){ + graph->setData(waveShowData.Key, waveShowData.wavedata_DC); + }else{ + if(m_iFormType == EnvChartPlot){ + graph->setData(waveShowData.Key, waveShowData.wavedataEnv); + }else{ + graph->setData(waveShowData.Key, waveShowData.wavedata); + } + } + graph->rescaleValueAxis(); + xRange = waveShowData.Key.size(); + graph->setName(waveShowData.channleName); + QPen pen; + pen.setColor(waveShowData.linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + graph->setPen(pen); + if(m_iFormType == FrequencyDomainPlot || m_iFormType == EnvChartPlot){ + ui->widget->xAxis->setRange(0, 1000); + } + + waveGraph.insert(listChannelID.at(i),graph); + } + } + + }else if(m_iFormType == OrbitPlot){ + ui->widget->clearPlottables(); + if(listChannelID.size() < 1) + return; + if(OrbitXWave.size() < 1 || OrbitYWave.size() < 1) + return; + double gap = (double)1/(double)OrbitXWave[position].SamleRate; + double f = 0.0; + qDebug() << "OrbitXWave" << OrbitXWave.size(); + QVector vecmainGraph1(OrbitXWave[position].waveData.size()),vecmainGraph2(OrbitYWave[position].waveData.size()); + for(int i = 0 ; i < OrbitXWave[position].waveData.size(); i++){ + f += gap; + vecmainGraph1[i].key = f; + vecmainGraph1[i].value = OrbitXWave[position].waveData[i]-OrbitXWave[position].mean; + } + mainGraph1 = ui->widget->addGraph(wideAxisRect1->axis(QCPAxis::atBottom), wideAxisRect1->axis(QCPAxis::atLeft)); + mainGraph1->data()->set(vecmainGraph1); + mainGraph1->rescaleAxes(); + mainGraph1->setPen(QPen(QColor(OrbitYWave[0].linColor), 2)); + + gap = (double)1/(double)OrbitYWave[position].SamleRate; + f = 0.0; + for(int i = 0 ; i < OrbitYWave[position].waveData.size(); i++){ + f += gap; + vecmainGraph2[i].key = f; + vecmainGraph2[i].value = OrbitYWave[position].waveData[i]-OrbitYWave[position].mean; + } + mainGraph2 = ui->widget->addGraph(wideAxisRect2->axis(QCPAxis::atBottom), wideAxisRect2->axis(QCPAxis::atLeft)); + mainGraph2->data()->set(vecmainGraph2); + mainGraph2->rescaleAxes(); + mainGraph2->setPen(QPen(QColor(OrbitXWave[0].linColor), 2)); + + fermatSpiral1 = new QCPCurve(wideAxisRectOrbit->axis(QCPAxis::atBottom), wideAxisRectOrbit->axis(QCPAxis::atLeft)); + int pointCount = OrbitXWave[0].wavesize; + QVector dataSpiral1(pointCount); //元素数组 + for (int i = 0; idata()->set(dataSpiral1, true); + fermatSpiral1->setPen(QPen(OrbitYWave[0].linColor)); + fermatSpiral1->rescaleAxes(); + QCPGraph* dwPoints = new QCPGraph(wideAxisRectOrbit->axis(QCPAxis::atBottom), wideAxisRectOrbit->axis(QCPAxis::atLeft)); + dwPoints->setAdaptiveSampling(false); + dwPoints->setLineStyle(QCPGraph::lsNone); + dwPoints->setScatterStyle(QCPScatterStyle::ssDot); + dwPoints->setPen(QPen(QBrush(Qt::white), 2)); + dwPoints->addData(vecKeyPhasor[position].key, vecKeyPhasor[position].value); + + + }else { + return; + } + ZoomBtnSlot_XY(); + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + + } +QPixmap ChildForm::GetSerise(QString& strImagePath) +{ + QPixmap pixmap = ui->widget->toPixmap(600,400); + QString PicName = ""; + switch(m_iFormType){ + case TimeDomainPlot: + PicName = "TimeDomain"; + break; + case FrequencyDomainPlot: + PicName = "FrequencyDomain"; + break; + case TrendChartPlot: + PicName = "TrendChart"; + break; + case SpecChartPlot: + PicName = "SpecChart"; + break; + case EnvChartPlot: + PicName = "EnvChart"; + break; + } + strImagePath = QCoreApplication::applicationDirPath() + "\\report\\" + PicName + ".png"; + ui->widget->savePng(strImagePath,600,400); + // =QWidget::grab(QRect(ui->widget->x(),ui->widget->y(),ui->widget->frameGeometry().width(),ui->widget->frameGeometry().height())); + return pixmap; +} +void ChildForm::AddShaftCenterlineSeries(QString strID, const QVector& wavexData,const QVector& waveyData) +{ + ui->widget->clearGraphs(); + foreach (auto ID, listChannelID){ + if(ID != strID){ + m_mapChannelIDtoLabel[ID]->setCheckState(Qt::Unchecked); + m_mapChannelIDtoLabel[ID]->setSelected(false); + } + } + QVector key,value; + + for (int i = 0; i < wavexData.size(); ++i) + { + double sum1 = std::accumulate(std::begin(wavexData[i].waveData), std::end(wavexData[i].waveData), 0.0); + double mean1 = sum1/(double)wavexData[i].waveData.size(); + key.push_back(mean1 - wavexData[0].sensorGapVoltage * 1000/wavexData[0].sensorSensitivity); + //qDebug() << sum1 << wavexData[i].waveData.size() << mean1 << key[0] << endl; + + } + + for (int i = 0; i < waveyData.size(); ++i) + { + double sum1 = std::accumulate(std::begin(waveyData[i].waveData), std::end(waveyData[i].waveData), 0.0); + double mean1 = sum1/(double)waveyData[i].waveData.size(); + value.push_back(mean1 - waveyData[0].sensorGapVoltage*1000/waveyData[0].sensorSensitivity); + } + + qDebug() << "AddShaftCenterlineSeries" << key.size() << value.size() << endl; + + QCPCurve* ShaftCenterline = new QCPCurve(ui->widget->xAxis, ui->widget->yAxis); + + /*QVector x(251), y0(251), y1(251); + for (int i=0; i<251; ++i) + { + x[i] = i; + y0[i] = qExp(-i/150.0)*qCos(i/10.0); // exponentially decaying cosine + y1[i] = qExp(-i/150.0); // exponential envelope + }*/ + + QVector dataSpiral1(value.size()); + for (int i = 0; i < value.size(); ++i) + { + dataSpiral1[i] = QCPCurveData(i, key[i], value[i]); + } + ShaftCenterline->data()->set(dataSpiral1,true); + ShaftCenterline->setPen(QPen(wavexData[0].linColor)); + //ShaftCenterline->setBrush(QBrush(QColor(0, 0, 255, 20))); + + ShaftCenterline->rescaleAxes(); + ui->widget->xAxis->setLabel(wavexData[0].sensorEngineeringUnit); + ui->widget->yAxis->setLabel(waveyData[0].sensorEngineeringUnit); + // ui->widget->xAxis->setRange(-1,1); + //ui->widget->yAxis->setRange(-1,1); + ShaftCenterline->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::red, 1.5), QBrush(Qt::red), 3));//散列点 + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + +} + +void ChildForm::AddBodeSeries(QString strID, const QVector& waveData,const QVector& waveSpeedData) +{ + /*mapBodeData.insert(strID,waveData); + if(mapBodeData.size() < 2){ + MyMsgBox(QMessageBox::Warning,"警告","请选择两条通道进行伯德图分析!"); + return ; + } + + QVector waveSpeedData; //转速 + QVector waveVibrateData; //振动 + QMap>::Iterator iter = mapBodeData.begin(); + for (;iter != mapBodeData.end() ; iter++) { + if(iter.value()[0].sensorType != "ACCELEROMETER" && iter.value()[0].sensorType != "TACHOMETER"){ + MyMsgBox(QMessageBox::Warning,"警告","请选择转速和振动通道进行伯德图分析"); + } + if(iter.value()[0].sensorType == "TACHOMETER"){ + waveSpeedData = iter.value(); + } + if(iter.value()[0].sensorType == "ACCELEROMETER"){ + waveVibrateData = iter.value(); + } + }*/ + foreach (auto ID, listChannelID){ + if(ID != strID){ + m_mapChannelIDtoLabel[ID]->setCheckState(Qt::Unchecked); + m_mapChannelIDtoLabel[ID]->setSelected(false); + } + } + ui->widget->plotLayout()->clear(); + ui->widget->clearGraphs(); + ui->widget->clearPlottables(); + + QCPAxisRect *wideAxisRect1 = new QCPAxisRect(ui->widget); + QCPAxisRect *wideAxisRect2 = new QCPAxisRect(ui->widget); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setTickLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setTickLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setTickLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setTickLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setBasePen(QPen(Qt::white, 1)); + + //wideAxisRect1->axis(QCPAxis::atBottom, 0)->setLabel(""); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setLabel("Degree Lag"); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setLabel("RPM"); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setLabel("mils(p-p)"); + + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setRange(-360,360); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setRange(0,8); + + + ui->widget->plotLayout()->addElement(0, 0, wideAxisRect1); // insert axis rect in first row + ui->widget->plotLayout()->addElement(1, 0, wideAxisRect2); + + QCPMarginGroup *marginGroup = new QCPMarginGroup(ui->widget); + wideAxisRect1->setMarginGroup(QCP::msLeft, marginGroup); + wideAxisRect2->setMarginGroup(QCP::msLeft, marginGroup); + + QCPGraph *mainGraph1 = ui->widget->addGraph(wideAxisRect1->axis(QCPAxis::atBottom), wideAxisRect1->axis(QCPAxis::atLeft)); + mainGraph1->rescaleAxes(); + mainGraph1->setPen(QPen(QColor(Qt::green), 2)); + + QCPGraph *mainGraph2 = ui->widget->addGraph(wideAxisRect2->axis(QCPAxis::atBottom), wideAxisRect2->axis(QCPAxis::atLeft)); + mainGraph2->rescaleAxes(); + mainGraph2->setPen(QPen(QColor(Qt::green), 2)); + + + QVector vecSpeedTime; + + /*for(int i = 0; i < waveSpeedData[0].Time;i++){ + + for(int j = 1; j < waveSpeedData.at(i).waveData.size();j++){ + if(waveSpeedData.at(i).waveData[j-1] < -18 && waveSpeedData.at(i).waveData[j] > -18 && \ + waveSpeedData.at(i).waveData[j-1] > -21){ + vecSpeedTime.push_back(j + (waveSpeedData[0].SamleRate * i)); + } + } + }*/ + for(int i = 0; i < waveSpeedData[0].Time;i++) + { + QVector vecTemp; + int flag = 0; + //qDebug() << "=====size====="<< waveSpeedData.at(i).waveData.size() << endl; + for(int j = 1; j < waveSpeedData.at(0).waveData.size();j++) + { + if(waveSpeedData.at(0).iTrigger == 0){ + if(waveSpeedData.at(i).waveData[j-1] > waveSpeedData.at(0).iTriggerValue && flag == 0){ + + flag = 1; + }else if(waveSpeedData.at(i).waveData[j-1] < (waveSpeedData.at(0).iTriggerValue-waveSpeedData.at(0).iHysteresis) && flag == 1){ + + flag = 0; + double time = (double)j/(double)waveSpeedData.at(0).SamleRate; + vecSpeedTime.push_back(j + (waveSpeedData[0].SamleRate * i)); + } + } + } + } + + + QVector vecmainGraph1; + QVector vecmainGraph2; + QVector vecSpeed; + double sum = 0.0; + qDebug() << "=====Speed=====" << vecSpeedTime[99] << vecSpeedTime[100] << endl; + { + + for(int j = 1;j < vecSpeedTime.size();j++){ + float Speed = float((vecSpeedTime[j]-vecSpeedTime[j-1])/(float)waveSpeedData[0].SamleRate); + Speed = (1/Speed * 60)/waveSpeedData[0].iKeyCount;//键齿数 + + /*QCPGraphData data; + data.key = j-1; + data.value = Speed; + vecmainGraph1.push_back(data);*/ + + RPM rpmData; + rpmData.key1 = vecSpeedTime[j-1]; + rpmData.key2 = vecSpeedTime[j]; + rpmData.fSpeed = Speed; + vecSpeed.push_back(rpmData); + //qDebug() << "=====Speed=====" << Speed << vecSpeedTime.at(j) << vecSpeedTime.at(j-1) << endl; + } + } + + QVector vecIncreaseSpeed; + for(int i = 1; i 10){//增速 + RPM rpmData; + rpmData.key1 = vecSpeed[i-1].key1; + rpmData.key2 = vecSpeed[i-1].key2; + rpmData.fSpeed = vecSpeed[i-1].fSpeed; + vecIncreaseSpeed.push_back(rpmData); + + + } + } + QVector VibrateData;//(waveVibrateData.size() * waveVibrateData[0].SamleRate); + VibrateData.reserve(waveData.size() * waveData[0].SamleRate); + for(int i = 0; i < waveData.size();i++){ + for(int j = 0 ;j < waveData[i].waveData.size();j++){ + VibrateData.push_back(waveData[i].waveData[j] - waveData[i].mean); + } + } + qDebug()<< "vecIncreaseSpeed"<< vecIncreaseSpeed.size() << endl; + for(int i = 0; i vecPP; + int Time1 = (float) vecIncreaseSpeed[i].key1/(waveSpeedData[0].SamleRate * waveSpeedData[0].Time) * waveData[0].SamleRate; + int Time2 = (float)(vecIncreaseSpeed[i].key2)/(waveSpeedData[0].SamleRate * waveSpeedData[0].Time)* waveData[0].SamleRate; + for (int i = Time1; i < Time2 ; i++) { + vecPP.push_back(VibrateData[i]); + } + qDebug() << "pp" << vecPP.size() << endl; + auto p1 = std::max_element(std::begin(vecPP), std::end(vecPP)); + auto p2 = std::min_element(std::begin(vecPP), std::end(vecPP)); + float Max = *p1; + float Min = *p2; + qDebug() << "=====Max====="<< *p1 << "===Min===" << *p2 << endl; + QCPGraphData data; + data.key = vecIncreaseSpeed[i].fSpeed; + data.value = Max - Min; + vecmainGraph2.push_back(data); + double Phase = pCalculation->Phase(vecPP); + qDebug() << "=====Phase1====="<< Phase << endl; + QCPGraphData data1; + data1.key = vecIncreaseSpeed[i].fSpeed; + data1.value = Phase; + vecmainGraph1.push_back(data1); + } + + mainGraph1 = ui->widget->addGraph(wideAxisRect1->axis(QCPAxis::atBottom), wideAxisRect1->axis(QCPAxis::atLeft)); + mainGraph1->data()->set(vecmainGraph1); + mainGraph1->rescaleKeyAxis(); + mainGraph1->setPen(QPen(QColor(waveData[0].linColor), 1)); + mainGraph1->setName("1"); + + mainGraph2 = ui->widget->addGraph(wideAxisRect2->axis(QCPAxis::atBottom), wideAxisRect2->axis(QCPAxis::atLeft)); + mainGraph2->data()->set(vecmainGraph2); + mainGraph2->rescaleKeyAxis(); + mainGraph2->setPen(QPen(QColor(waveData[0].linColor), 1)); + mainGraph2->setName("2"); + ui->widget->replot(); + +} +void ChildForm::AddOrbitSeries(QString strID, const QVector& wavexData,const QVector& waveyData,\ + const QVector& waveSpeedData) + { + QVector().swap(OrbitXWave); + QVector().swap(OrbitYWave); + QVector().swap(vecKeyPhasor); + + foreach (auto ID, listChannelID){ + if(ID != strID){ + m_mapChannelIDtoLabel[ID]->setCheckState(Qt::Unchecked); + m_mapChannelIDtoLabel[ID]->setSelected(false); + } + } + + + OrbitXWave = wavexData; + OrbitYWave = waveyData; + ui->widget->plotLayout()->clear(); + + wideAxisRect1 = new QCPAxisRect(ui->widget); + wideAxisRect2 = new QCPAxisRect(ui->widget); + wideAxisRectOrbit = new QCPAxisRect(ui->widget); + + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setTickLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setTickLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setLabelColor(Qt::white); + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setTickLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setTickLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setLabelColor(Qt::white); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRectOrbit->axis(QCPAxis::atLeft, 0)->setTickLabelColor(Qt::white); + wideAxisRectOrbit->axis(QCPAxis::atLeft, 0)->setLabelColor(Qt::white); + wideAxisRectOrbit->axis(QCPAxis::atLeft, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRectOrbit->axis(QCPAxis::atBottom, 0)->setTickLabelColor(Qt::white); + wideAxisRectOrbit->axis(QCPAxis::atBottom, 0)->setLabelColor(Qt::white); + wideAxisRectOrbit->axis(QCPAxis::atBottom, 0)->setBasePen(QPen(Qt::white, 1)); + + wideAxisRect1->axis(QCPAxis::atBottom, 0)->setLabel("Time(s)"); + wideAxisRect1->axis(QCPAxis::atLeft, 0)->setLabel(wavexData[0].sensorEngineeringUnit); + wideAxisRect2->axis(QCPAxis::atBottom, 0)->setLabel("Time(s)"); + wideAxisRect2->axis(QCPAxis::atLeft, 0)->setLabel(waveyData[0].sensorEngineeringUnit); + wideAxisRectOrbit->axis(QCPAxis::atBottom, 0)->setLabel(wavexData[0].sensorEngineeringUnit); + wideAxisRectOrbit->axis(QCPAxis::atLeft, 0)->setLabel(waveyData[0].sensorEngineeringUnit); + + QCPLayoutGrid *subLayout = new QCPLayoutGrid; + ui->widget->plotLayout()->addElement(0, 1, subLayout); // insert axis rect in first row + ui->widget->plotLayout()->addElement(0, 0, wideAxisRectOrbit); + subLayout->addElement(0, 0, wideAxisRect1); + subLayout->addElement(1, 0, wideAxisRect2); + double gap = (double)1/(double)wavexData[0].SamleRate; + double f = 0.0; + QVector vecmainGraph1(wavexData[0].waveData.size()),vecmainGraph2(waveyData[0].waveData.size()); + for(int i = 0 ; i < wavexData[0].waveData.size(); i++){ + f += gap; + vecmainGraph1[i].key = f; + vecmainGraph1[i].value = wavexData[0].waveData[i]-wavexData[0].mean; + } + + mainGraph1 = ui->widget->addGraph(wideAxisRect1->axis(QCPAxis::atBottom), wideAxisRect1->axis(QCPAxis::atLeft)); + mainGraph1->data()->set(vecmainGraph1); + mainGraph1->rescaleAxes(); + mainGraph1->setPen(QPen(QColor(waveyData[0].linColor), 2)); + + gap = (double)1/(double)waveyData[0].SamleRate; + f = 0.0; + for(int i = 0 ; i < waveyData[0].waveData.size(); i++){ + f += gap; + vecmainGraph2[i].key = f; + vecmainGraph2[i].value = waveyData[0].waveData[i]-waveyData[0].mean; + } + + mainGraph2 = ui->widget->addGraph(wideAxisRect2->axis(QCPAxis::atBottom), wideAxisRect2->axis(QCPAxis::atLeft)); + mainGraph2->data()->set(vecmainGraph2); + mainGraph2->rescaleAxes(); + mainGraph2->setPen(QPen(QColor(wavexData[0].linColor), 2)); + + fermatSpiral1 = new QCPCurve(wideAxisRectOrbit->axis(QCPAxis::atBottom), wideAxisRectOrbit->axis(QCPAxis::atLeft)); + int pointCount = wavexData[0].wavesize; + QVector dataSpiral1(pointCount); //元素数组 + qDebug() << wavexData[0].waveData.at(10) << waveyData[0].waveData.at(10) << endl; + for (int i=0; idata()->set(dataSpiral1, true); + fermatSpiral1->setPen(QPen(waveyData[0].linColor)); + fermatSpiral1->rescaleAxes(); + + QVector> vecSpeedTime; + qDebug() << "=====Time====="<< waveSpeedData[0].Time << endl; + qDebug() << "=====wavexData size====="<< wavexData.size() << endl; + int iTime = 0; + if(wavexData.size() <= waveSpeedData[0].Time)//防止Dat文件数据丢失,取实际读到的秒数 + iTime = wavexData.size(); + for(int i = 0; i < iTime;i++) + { + QVector vecTemp; + int flag = 0; + qDebug() << "=====size====="<< waveSpeedData.at(i).waveData.size() << endl; + for(int j = 1; j < waveSpeedData.at(0).waveData.size();j++) + { + if(waveSpeedData.at(0).iTrigger == 0){ + if(waveSpeedData.at(i).waveData[j-1] > waveSpeedData.at(0).iTriggerValue && flag == 0){ + + flag = j; + }else if(waveSpeedData.at(i).waveData[j-1] < (waveSpeedData.at(0).iTriggerValue-waveSpeedData.at(0).iHysteresis) && flag > 0){ + + + double time = (double)flag/(double)waveSpeedData.at(0).SamleRate; + vecTemp.push_back(time); + flag = 0; + } + } + } + vecSpeedTime.push_back(vecTemp); + qDebug() << "=====vecSpeedTime====="<< vecSpeedTime.size()<< endl; + } + + qDebug() << "=====vecSpeedTime====="<< vecSpeedTime[10][10]<< endl; + QVector key,value; + for(int j = 0;j < vecSpeedTime.size();j++) + { + KeyPhasor keyphasor; + for(int i = 0 ;i < vecSpeedTime[j].size();i++){ + keyphasor.key.push_back(OrbitXWave[j].waveData[vecSpeedTime[j][i]*OrbitXWave[0].SamleRate]-OrbitXWave[0].mean); + keyphasor.value.push_back(OrbitYWave[j].waveData[vecSpeedTime[j][i]*OrbitYWave[0].SamleRate]-OrbitYWave[0].mean); + } + vecKeyPhasor.push_back(keyphasor); + } + qDebug() << "=====vecKeyPhasor====="<< vecKeyPhasor.size()<< endl; + + //保留 + /*keyPhasor = ui->widget->addGraph(wideAxisRectOrbit->axis(QCPAxis::atBottom), wideAxisRectOrbit->axis(QCPAxis::atLeft)); + keyPhasor->data()->set(vecKeyPhasor); + keyPhasor->rescaleAxes(); + QPen drawPen; + drawPen.setColor(Qt::red); + drawPen.setWidth(4); + keyPhasor->setPen(drawPen); + keyPhasor->setLineStyle(QCPGraph::lsNone); + keyPhasor->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2));*/ + // + + QCPGraph* dwPoints = new QCPGraph(wideAxisRectOrbit->axis(QCPAxis::atBottom), wideAxisRectOrbit->axis(QCPAxis::atLeft)); + dwPoints->setAdaptiveSampling(false); + dwPoints->setLineStyle(QCPGraph::lsNone); + dwPoints->setScatterStyle(QCPScatterStyle::ssDot); + dwPoints->setPen(QPen(QBrush(Qt::white), 2)); + + dwPoints->addData(vecKeyPhasor[0].key, vecKeyPhasor[0].value); + //dwPoints->rescaleAxes(); + + ui->widget->replot(); + } +void ChildForm::AddPolarPlotSeries(QString strID, const QVector& wavexData,const QVector& waveSpeedData) + { + qDebug() << "=====AddPolarPlotSeries=====" <setCheckState(Qt::Unchecked); + m_mapChannelIDtoLabel[ID]->setSelected(false); + } + } + ui->widget->plotLayout()->clear(); + + QVector vecMeanRPM; + QVector ValueAmp; + QVector keyPhase; + qDebug() << "=====waveSpeedData time=====" < vecTemp; + QVector vecSpeedTime; + int flag = 0; + for(int j = 1; j < waveSpeedData.at(i).waveData.size();j++) + { + if(waveSpeedData.at(0).iTrigger == 0){ + if(waveSpeedData.at(i).waveData[j-1] > waveSpeedData.at(0).iTriggerValue && flag == 0){ + + flag = 1; + }else if(waveSpeedData.at(i).waveData[j-1] < (waveSpeedData.at(0).iTriggerValue-waveSpeedData.at(0).iHysteresis) && flag == 1){ + + flag = 0; + vecSpeedTime.push_back(j + (waveSpeedData[0].SamleRate * i)); + } + } + } + + QVector vecSpeed; + double SumRPM = 0.0; + for(int j = 1;j < vecSpeedTime.size();j++){ + float Speed = float((vecSpeedTime[j]-vecSpeedTime[j-1])/(float)waveSpeedData[0].SamleRate); + Speed = (1/Speed * 60)/waveSpeedData[0].iKeyCount;//键齿数 + + /*QCPGraphData data; + data.key = j-1; + data.value = Speed; + vecmainGraph1.push_back(data);*/ + + RPM rpmData; + rpmData.key1 = vecSpeedTime[j-1]; + rpmData.key2 = vecSpeedTime[j]; + rpmData.fSpeed = Speed; + vecSpeed.push_back(rpmData); + SumRPM += Speed; + qDebug() << "=====Speed=====" << Speed << vecSpeedTime.at(j) << vecSpeedTime.at(j-1) << endl; + } + double MeanRPM = SumRPM/(double)vecSpeed.size(); + vecMeanRPM.push_back(MeanRPM); + } + qDebug() << "=====vecMeanRPM=====" < vecEnvSpecData; + QVector vecData; + + double hz = (double)vecMeanRPM[k]/(double)60; + + for(int j = 0; j < wavexData[k].SamleRate;j++){ + + float fData = wavexData[k].waveData.at(j)-wavexData[k].mean; + vecData.push_back(fData); + } + + int start = hz-hz*0.05; + int end = hz+hz*0.05; + + pCalculation->envSpec(vecData,vecEnvSpecData,start,end,true); + + double Sum = 0.0; + double DataSum = std::accumulate(std::begin(vecEnvSpecData), std::end(vecEnvSpecData), 0.0); + double Datamean = DataSum/(double)vecEnvSpecData.size(); + for(int j = 0; j < vecEnvSpecData.size();j++){ + double fData = vecEnvSpecData.at(j) - Datamean; + fData = fData*fData; + Sum += fData; + } + double rms = sqrt(Sum/(double)vecEnvSpecData.size()); //加速度有效值 + + QVector vecFFTrealData,vecFFTimageData; + QVector vecData1; + for(int i = 0; i < wavexData[k].SamleRate;i++){ + vecData1.push_back(wavexData[k].waveData[i]); + } + pCalculation->_FFT(vecData1,vecFFTrealData,vecFFTimageData); + + double real = vecFFTrealData[(int)hz]; + double image = vecFFTimageData[(int)hz]; + + double phase = atan2(image,real)*180/3.14; + ValueAmp.push_back(rms); + keyPhase.push_back(phase); + + } + + QCPPolarAxisAngular *angularAxis = new QCPPolarAxisAngular(ui->widget); + ui->widget->plotLayout()->addElement(0, 0, angularAxis); + /* This is how we could set the angular axis to show pi symbols instead of degree numbers: + QSharedPointer ticker(new QCPAxisTickerPi); + ticker->setPiValue(180); + ticker->setTickCount(8); + polarAxis->setTicker(ticker); + */ + ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); + angularAxis->setRangeDrag(false); + angularAxis->setTickLabelMode(QCPPolarAxisAngular::lmUpright); + +// angularAxis->radialAxis()->setTickLabelMode(QCPPolarAxisRadial::lmUpright); +// angularAxis->radialAxis()->setTickLabelRotation(0); +// angularAxis->radialAxis()->setAngle(45); + +// angularAxis->grid()->setAngularPen(QPen(QColor(200, 200, 200), 0, Qt::SolidLine)); +// angularAxis->grid()->setSubGridType(QCPPolarGrid::gtAll); + + QCPPolarGraph *g1 = new QCPPolarGraph(angularAxis, angularAxis->radialAxis()); +// QCPPolarGraph *g2 = new QCPPolarGraph(angularAxis, angularAxis->radialAxis()); +// g2->setPen(QPen(QColor(255, 150, 20))); +// g2->setBrush(QColor(255, 150, 20, 50)); +// g1->setScatterStyle(QCPScatterStyle::ssDisc); +// for (int i=0; i<100; ++i) +// { +// g1->addData(i/100.0*360.0, qSin(i/100.0*M_PI*8)*8+1); +// g2->addData(i/100.0*360.0, qSin(i/100.0*M_PI*6)*2); +// } + QPen pen; + pen.setColor(wavexData.at(0).linColor); + pen.setStyle(Qt::SolidLine); + + pen.setWidth(2); + g1->setPen(pen); + g1->addData(keyPhase,ValueAmp); + angularAxis->setRange(0, 360); + angularAxis->radialAxis()->setRange(-10, 10); + //坐标轴为白色 + angularAxis->setBasePen(QPen(Qt::white, 1)); + + //坐标轴的提示信息为白色 + angularAxis->setTickLabelColor(Qt::white); + + angularAxis->setLabelColor(Qt::white); + angularAxis->radialAxis()->setLabelColor(Qt::white); + angularAxis->radialAxis()->setTickLabelColor(Qt::white); + + g1->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::red, 1.5), QBrush(Qt::red), 3));//散列点 + ui->widget->replot(); + } +void ChildForm::ChannelBtnSlot() +{ + ui->ChannelWgt->setVisible(!ui->ChannelWgt->isVisible()); + QString strStyle; + if(ui->ChannelWgt->isVisible()) + { + strStyle = "#ChannelBtn{border-image:url(:/images/images/hideChannel.png);}"; + } + else + { + strStyle = "#ChannelBtn{border-image:url(:/images/images/showChannel.png);}"; + } + ui->ChannelBtn->setStyleSheet(strStyle); +} +void ChildForm::ClearTable() +{ + for (int i = 0; i < ui->tableWidget->rowCount(); ++i) + { + QTableWidgetItem *pItem = ui->tableWidget->itemAt(i, 0); + QTableWidgetItem *pItem1 = ui->tableWidget->itemAt(i, 1); + + if(pItem) delete pItem; + if(pItem1) delete pItem1; + } + ui->tableWidget->clearContents(); + ui->tableWidget->setRowCount(0); +} +void ChildForm::ClearAllSerise() +{ + if(!m_pChart) + return; + m_pChart->removeAllSeries(); + qDebug()<<"ChildForm::ClearAllSerise()" << m_pChart->axes().size(); + + while (m_pChart->axes().size()) + { + m_pChart->removeAxis(m_pChart->axes().at(0)); + } + QValueAxis *axisX = new QValueAxis; + axisX->setLinePenColor(Qt::gray); + m_pChart->addAxis(axisX, Qt::AlignBottom); + + QValueAxis *axisY = new QValueAxis; + axisY->setLinePenColor(Qt::gray); + m_pChart->addAxis(axisX, Qt::AlignLeft); + + m_bAttach = false; +} +QTableWidgetItem * ChildForm::AddTableWgtItem(QString strText, QString clolor, QString strID) +{ + ui->tableWidget->setRowCount(ui->tableWidget->rowCount() + 1); + ui->tableWidget->setColumnWidth(0, 226); + ui->tableWidget->setColumnWidth(1, 20); + QTableWidgetItem *pItemName = new QTableWidgetItem(); + pItemName->setText(strText); + pItemName->setCheckState(Qt::Unchecked); + + + QWidget *pWgt = new QWidget; + QVBoxLayout *pLayout = new QVBoxLayout(pWgt); + QLabel *pLabel = new QLabel(ui->tableWidget); + pLabel->setFixedSize(20, 20); + pLabel->setStyleSheet(QString("QLabel{background: rgb(%1)}").arg(clolor)); + pLayout->addWidget(pLabel); + pLayout->setMargin(0); //设置边缘距离 否则会很难看 + pLayout->setAlignment(pLabel, Qt::AlignCenter); + + + ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, pItemName); + ui->tableWidget->setCellWidget(ui->tableWidget->rowCount() - 1, 1, pWgt); + + m_mapChannelIDtoLabel[strID] = pItemName; + return pItemName; +} +void ChildForm::SetDataIDs(const QStringList &strIDList, QString strTitle,const QStringList& strChannleTypeList,\ + const QStringList& strChannleNameList) +{ + if(m_pLegendForm) m_pLegendForm->SetChannelIDs(strIDList); + + ui->label_title->setText(strTitle); + disconnect(ui->tableWidget, SIGNAL(itemPressed(QTableWidgetItem *)), this, SLOT(ItemPressSlot(QTableWidgetItem *))); + disconnect(ui->tableWidget, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(ItemChangedSlot(QTableWidgetItem *))); + m_listChannelID = strIDList; + int i = 0; + for(int j = 0; j < strIDList.size();j++) + { + QString strNum1 = strIDList[j].right(2).left(1); + QString strNum2 = strIDList[j].right(1); + QString strChannleType = ""; + if(strChannleTypeList[j] == "ACCELEROMETER") + { + strChannleType = "加速度"; + }else if(strChannleTypeList[j] == "PROXIMETER"){ + strChannleType = "径向位移"; + }else if(strChannleTypeList[j] == "VELOCITY"){ + strChannleType = "速度"; + }else if(strChannleTypeList[j] == "SLOW_CURRENT"){ + strChannleType = "电流"; + }else if(strChannleTypeList[j] == "THRUST"){ + strChannleType = "轴向位移"; + }else if(strChannleTypeList[j] == "TACHOMETER"){ + strChannleType = "转速"; + }else if(strChannleTypeList[j] == "MICROPHONE"){ + strChannleType = "声音"; + }else if(strChannleTypeList[j] == "FAST_VOLTAGE"){ + strChannleType = "动态电压"; + } + + QString strText = QStringLiteral("%1-%2%3 (%4)").arg(strChannleNameList[j]).arg(strNum1).arg(strNum2).arg(strChannleType); + //QString strText = QStringLiteral("%1").arg(strChannleType[j]); + QString strColor = "0,255,0"; + switch(i){ + case 0: + strColor = "0,255,0"; + break; + case 1: + strColor = "30,144,255"; + break; + case 2: + strColor = "255,182,193"; + break; + case 3: + strColor = "0, 255, 255"; + break; + case 4: + strColor = "255, 0, 255"; + break; + case 5: + strColor = "255, 255, 0"; + break; + case 6: + strColor = "255,69,0"; + break; + case 7: + strColor = "0, 255, 127"; + break; + case 8: + strColor = "255,140,0"; + break; + case 9: + strColor = "0, 191, 255"; + break; + case 10: + strColor = "139, 0, 139"; + break; + case 11: + strColor = "211, 211, 211"; + break; + case 12: + strColor = "205, 205, 0"; + break; + case 13: + strColor = "198, 226, 255"; + break; + case 14: + strColor = "255, 218, 185"; + break; + case 15: + strColor = "255, 20, 147"; + break; + default: + break; + } + i++; + QTableWidgetItem *pItem = AddTableWgtItem(strText, strColor, strIDList[j]); + pItem->setData(CHANNELID_ROLE, strIDList[j]); + pItem->setData(CHANNELTYPE_ROLE, strChannleTypeList[j]); + } + + connect(ui->tableWidget, SIGNAL(itemPressed(QTableWidgetItem *)), this, SLOT(ItemPressSlot(QTableWidgetItem *))); + connect(ui->tableWidget, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(ItemChangedSlot(QTableWidgetItem *))); + m_mapChannelIDtoLabel[strIDList[0]]->setSelected(true); + m_mapChannelIDtoLabel[strIDList[0]]->setCheckState(Qt::Checked); + + listChannelID.push_back(strIDList[0]); + emit ItemCheckStateSignal(strIDList[0], true); +} +void ChildForm::RemoveSeries(QString strID) +{ + qDebug()<<"::ChildForm::RemoveSeries" <widget->clearGraphs(); + ui->widget->clearPlottables(); + qDebug() << ui->widget->graphCount() << endl; + line = 0; + }else if(m_iFormType == TrendChartPlot || m_iFormType == TimeDomainPlot || m_iFormType == FrequencyDomainPlot || m_iFormType == EnvChartPlot){ + QMap>::Iterator itermultiGraph = mapMultiGraph.begin(); + + for(;itermultiGraph != mapMultiGraph.end();itermultiGraph++){ + int flag = 0; + QMap::Iterator iterGraph = itermultiGraph.value().begin(); + for(;iterGraph != itermultiGraph.value().end();iterGraph++){ + if(iterGraph.key() == strID){ + if(mapMultiGraph[itermultiGraph.key()].size() == 1){ + iterGraph.value()->setVisible(false); + } + mapMultiGraph[itermultiGraph.key()].erase(iterGraph); + } + if(mapMultiGraph[itermultiGraph.key()].size() == 0){ + flag = 1; + break; + } + } + if(flag ==1){ + mapMultiGraph.erase(itermultiGraph); + } + if(mapMultiGraph.size() == 0) + break; + } + QMap::Iterator iter = waveGraph.begin(); + for(iter = waveGraph.begin();iter != waveGraph.end();iter++) + { + if(strID == iter.key()){ + qDebug() << strID << endl; + ui->widget->removeGraph(iter.value()); + line --; + qDebug() << "line" << line << endl; + int graphCount = ui->widget->graphCount(); + qDebug() << "graphCount" << graphCount<< endl; + + QMap::Iterator iter1 = mapWaveDisplayData.begin(); + for(iter1 = mapWaveDisplayData.begin();iter1 != mapWaveDisplayData.end();iter1++){ + if(strID == iter1.key()) + mapWaveDisplayData.erase(iter1); + if(mapWaveDisplayData.size() == 0) + break; + } + waveGraph.erase(iter); + if(m_bRealTime){ + QString topicPub = QString("up/%1/recive/waveserver").arg(m_DeviceInfo->DeviceMac);//推送 + QJsonArray channel_Arr; + QJsonObject root_Obj; + QJsonObject item_Obj; + item_Obj.insert("channelId",strID); + item_Obj.insert("flag",1); + channel_Arr.insert(0,item_Obj); + root_Obj.insert("type","STOP"); + root_Obj.insert("channelArray",channel_Arr); + QJsonDocument root_Doc; + root_Doc.setObject(root_Obj); + QByteArray root_str = root_Doc.toJson(QJsonDocument::Compact); + QString strJson(root_str); + qDebug() << strJson << endl; + QMQTT::Message message(136,topicPub,strJson.toUtf8()); + mqttclient->Push(message); + } + } + if(waveGraph.size() == 0){ + m_bRealTime = false; + ui->realTimeDataBtn->setChecked(false); + EnableBtn(); + break; + } + + } + + } + else{ + QMap::Iterator iter = waveGraph.begin(); + for(iter = waveGraph.begin();iter != waveGraph.end();iter++) + { + if(strID == iter.key()){ + qDebug() << strID << endl; + ui->widget->removeGraph(iter.value()); + line --; + int graphCount = ui->widget->graphCount(); + qDebug() << "graphCount" << graphCount<< endl; + + QMap::Iterator iter1 = mapWaveDisplayData.begin(); + for(iter1 = mapWaveDisplayData.begin();iter1 != mapWaveDisplayData.end();iter1++){ + if(strID == iter1.key()) + mapWaveDisplayData.erase(iter1); + } + waveGraph.erase(iter); + } + + } + QMap>::Iterator iter1 = mapBodeData.begin(); + for (;iter1 != mapBodeData.end() ; iter1++) { + if(strID == iter1.key()){ + QVector().swap(iter1.value()); + mapBodeData.erase(iter1); + } + } + } + + if(m_bIntegration) + m_bIntegration = false; + + if(m_bDifferentiation) + m_bDifferentiation = false; + + if(m_bRpm) + m_bRpm = false; + + ui->widget->replot(); + + if(tracerLabel->visible()) + tracerLabel->setVisible(false); + if(tracerLabel2->visible()) + tracerLabel2->setVisible(false); + if(tracerLabel3->visible()) + tracerLabel3->setVisible(false); + if(tracerLabel4->visible()) + tracerLabel4->setVisible(false); + if(tracerLabel5->visible()) + tracerLabel5->setVisible(false); + + + //disconnect(dismove); + disconnect(disPress); + ZoomBtnSlot_XY(); + UpdateDiffMenu(); + +} +void ChildForm::ItemPressSlot(QTableWidgetItem *item) +{ + if(m_bRealTime){ + realTimeData(); + MyMsgBox(QMessageBox::Information,"提示","请先暂停实时数据播放!"); + return; + } + if(!item) return; + if(item->column() != 0) return; + + QString strID = item->data(CHANNELID_ROLE).toString(); + if(item->isSelected() && !item->checkState()) + { + if(ui->widget->graphCount() == 3){ + + item->setCheckState(Qt::Unchecked); + item->setSelected(false); + return; + } + item->setCheckState(Qt::Checked); + emit ItemCheckStateSignal(strID, true); + listChannelID.push_back(strID); + } + else if(item->checkState() && !item->isSelected()) + { + item->setCheckState(Qt::Unchecked); + emit ItemCheckStateSignal(strID, false); + listChannelID.removeOne(strID); + RemoveSeries(strID); + } + +} +void ChildForm::ItemChangedSlot(QTableWidgetItem *item) +{ + if(m_bRealTime){ + realTimeData(); + return; + } + if(!item) return; + if(item->column() != 0) return; + + QString strID = item->data(CHANNELID_ROLE).toString(); + QString strType = item->data(CHANNELTYPE_ROLE).toString(); + if(item->checkState() && !item->isSelected()) + { + if(ui->widget->graphCount() == 3 && m_iFormType != OrbitPlot){ + MyMsgBox(QMessageBox::Information,"提示","最大支持三条曲线"); + item->setCheckState(Qt::Unchecked); + item->setSelected(false); + return; + } + item->setCheckState(Qt::Checked); + item->setSelected(true); + emit ItemCheckStateSignal(strID, true); + listChannelID.push_back(strID); + } + else if(!item->checkState() && item->isSelected()) + { + item->setCheckState(Qt::Unchecked); + item->setSelected(false); + emit ItemCheckStateSignal(strID, false); + listChannelID.removeOne(strID); + RemoveSeries(strID); + + } + +} +void ChildForm::mouseMoveEvent(QMouseEvent *event) +{ + + //将像素点转换成qcustomplot中的坐标值,并通过setGraphKey将锚点值设为真实数据值。tracer->setGraphKey(xAxis->pixelToCoord(event->pos().x())); + int graphCount = ui->widget->graphCount(); + if(graphCount < 1) + return; + //获得鼠标位置处对应的横坐标数据x + double x = 0.0; + if(m_iFormType == BodePlot){ + + x = ui->widget->axisRect(1)->axis(QCPAxis::atBottom,0)->pixelToCoord(event->pos().x()); + //遍历曲线 + //for (int i = 0; i < graphCount; ++i) + { + + //显示锚点 + QCPGraph *mGraph = ui->widget->graph(0); + tracer->setVisible(true); + tracerLabel->setVisible(true); + tracerLabel->setPositionAlignment(Qt::AlignLeft); + tracerLabel->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel->position->setCoords(0, 0); + tracer->setGraph(mGraph);//将锚点设置到被选中的曲线上 + { + tracer->setGraphKey(x); + //tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + + double y = ui->widget->axisRect(0)->axis(QCPAxis::atLeft)->pixelToCoord(event->pos().y()); + + double xValue = tracer->position->key(); + double yValue = y; + //显示tip框 + QCPDataContainer::const_iterator coorPoint = ui->widget->graph(0)->data().data()->findBegin(x, true);//true代表向左搜索 + tracer->setGraphKey(coorPoint->key); + //tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + + tracerLabel->setText(QString("%1 X: %2 Y: %3").arg(mGraph->name()).arg( QString::number(x)).arg(QString::number(yValue))); + } + + //显示锚点 + QCPGraph *mGraph2 = ui->widget->graph(1); + tracerLabel3->setVisible(true); + tracerLabel3->setPositionAlignment(Qt::AlignVCenter); + tracerLabel3->position->setType(QCPItemPosition::ptAxisRectRatio);//位置类型(当前轴范围的比例为单位/实际坐标为单位) + tracerLabel3->position->setCoords(10, 20); + tracer->setGraph(mGraph2);//将锚点设置到被选中的曲线上 + { + tracer->setGraphKey(x); + //tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + + double y2 = ui->widget->axisRect(1)->axis(QCPAxis::atLeft)->pixelToCoord(event->pos().y()); + + double xValue = tracer->position->key(); + double yValue2 = y2; + //显示tip框 + QCPDataContainer::const_iterator coorPoint = ui->widget->graph(1)->data().data()->findBegin(x, true);//true代表向左搜索 + tracer->setGraphKey(coorPoint->key); + //tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + + tracerLabel3->setText(QString("%1 X: %2 Y: %3").arg(mGraph2->name()).arg( QString::number(x)).arg(QString::number(yValue2))); + } + } + + }else{ + x = ui->widget->xAxis->pixelToCoord(event->pos().x()); + + //遍历曲线 + for (int i = 0; i < graphCount; ++i) + { + //显示锚点 + QCPGraph *mGraph = ui->widget->graph(i); + tracer->setVisible(true); + + + tracer->setGraph(mGraph);//将锚点设置到被选中的曲线上 + tracer->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x + //tracer->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + double xValue = tracer->position->key(); + double yValue = tracer->position->value(); + if( i == 0){ + tracerLabel->setVisible(true); + tracerLabel->setText(QString("%1 X: %2 Y: %3").arg(mGraph->name()).arg( QString::number(xValue)).arg(QString::number(yValue))); + } + else if( i == 1){ + tracerLabel3->setVisible(true); + tracerLabel3->setText(QString("%1 X: %2 Y: %3").arg(mGraph->name()).arg( QString::number(xValue)).arg(QString::number(yValue))); + }else if( i == 2){ + tracerLabel4->setVisible(true); + tracerLabel4->setText(QString("%1 X: %2 Y: %3").arg(mGraph->name()).arg( QString::number(xValue)).arg(QString::number(yValue))); + }else if( i == 3){ + tracerLabel5->setVisible(true); + tracerLabel5->setText(QString("%1 X: %2 Y: %3").arg(mGraph->name()).arg( QString::number(xValue)).arg(QString::number(yValue))); + } + //显示tip框 + QCPDataContainer::const_iterator coorPoint = ui->widget->graph(i)->data().data()->findBegin(xValue, true);//true代表向左搜索 + + } + } + //重绘 + ui->widget->replot(); +} + +void ChildForm::mouseDoubleClickEvent(QMouseEvent *event) +{ + int graphCount = ui->widget->graphCount(); + if(graphCount < 1) + return; + qDebug()<<"mouseDoubleClickEvent" << endl; + double x = ui->widget->xAxis->pixelToCoord(event->pos().x()); + //遍历曲线 + for (int i = 0; i < graphCount; ++i) + { + if(ui->widget->graph(i)->selected()){ + QCPGraph *mGraph = ui->widget->graph(i); + tracer2->setVisible(true); + tracerLabel2->setVisible(true); + mGraph = ui->widget->graph(i); + double x = ui->widget->xAxis->pixelToCoord(event->pos().x()); + tracer2->setGraph(mGraph);//将锚点设置到被选中的曲线上 + tracer2->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x + //tracer2->setInterpolating(true); //游标的纵坐标可以通过曲线数据线性插值自动获得 + tracer2->updatePosition(); //使得刚设置游标的横纵坐标位置生效 + tracerLabel2->position->setParentAnchor(tracer2->position); + double xValue = tracer2->position->key(); + double yValue = tracer2->position->value(); + //显示tip框 + tracerLabel2->setText(QString("%1 \n X: %2 \n Y: %3").arg(mGraph->name()).arg( QString::number(xValue)).arg(QString::number(yValue))); + } + } +} +void ChildForm::mouseWheelEvent(QWheelEvent *event) +{ + + int graphCount = ui->widget->graphCount(); + QCPRange range = ui->widget->xAxis->range(); + //qDebug() << range.size() << endl; + for (int i = 0; i < graphCount; ++i){ + switch (m_iFormType) { + case TimeDomainPlot: + if(range.size() < 0.01){ + ui->widget->graph(i)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::red, 1.5), QBrush(Qt::red), 3));//散列点 + }else if(range.size() > 0.01){ + ui->widget->graph(i)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 1.5), QBrush(Qt::blue), 3));//散列点 + } + break; + case FrequencyDomainPlot: + case TrendChartPlot: + case EnvChartPlot: + if(range.size() < 100){ + ui->widget->graph(i)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, QPen(Qt::red, 1.5), QBrush(Qt::red), 3));//散列点 + }else if(range.size() > 100){ + ui->widget->graph(i)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 1.5), QBrush(Qt::blue), 3));//散列点 + } + break; + } + } + ui->widget->replot(); +} + +void ChildForm::CalculateRPM() +{ + ui->widget->clearGraphs(); + QMap().swap(waveGraph); + QMap::iterator iter = mapWaveDisplayData.begin(); + for(; iter != mapWaveDisplayData.end();iter++){ + if(iter.value().channelType == "TACHOMETER"){ + + QVector vecWaveDisplay; + +// QString filename = QString("e://Speed.csv"); +// QFile file(filename); +// qDebug()<< "filename = "< vecSpeedTime; + int flag = 0; + qDebug() << "wavedata.size()" << iter.value().wavedata_DC.size(); + for(int i = 0; i < iter.value().wavedata_DC.size();i++){ + + if(iter.value().iTrigger == 0){//上升沿 + + if((iter.value().wavedata_DC[i]) > iter.value().iTriggerValue && flag == 0){ + + flag = i; + + }else if (iter.value().wavedata_DC[i] < (iter.value().iTriggerValue - iter.value().iHysteresis) && flag > 0){ + + vecSpeedTime.push_back(flag); + flag = 0; + } + }/*else if(iter.value()[j].iTrigger == 1){//下降沿 + if((iter.value()[j].waveData[i-1])> iter.value()[j].iTriggerValue &&\ + (iter.value()[j].waveData[i]) < iter.value()[j].iTriggerValue && \ + (iter.value()[j].waveData[i-1]) < (iter.value()[j].iTriggerValue + iter.value()[j].iHysteresis)){ + + vecSpeedTime.push_back(i); + } + }*/ + } + WAVE_DISPALYDATA WaveDisplay; + qDebug() << "vecSpeedTime " << vecSpeedTime.size() << endl; + double sum = 0.0; + double gap = (double)1/(double)vecSpeedTime.size(); + double key = 0.0; + for(int jj = 1;jj < vecSpeedTime.size();jj++){ + //out << (float)vecSpeedTime[jj-1]/(float)SamleRate + j << ","; + //out << "\n"; + float Speed = float((vecSpeedTime[jj]-vecSpeedTime[jj-1])/(float)iter.value().SamleRate); + Speed = (1/Speed * 60)/iter.value().iKeyCount;//键齿数 计算每分钟转速 + key += gap; + WaveDisplay.Key.push_back(key); + WaveDisplay.wavedata.push_back(Speed); + sum += Speed; + } + + WaveDisplay.meanRpm = sum/(double)WaveDisplay.wavedata.size(); + WaveDisplay.linColor = iter.value().linColor; + WaveDisplay.channelType = iter.value().channelType; + WaveDisplay.sensorEngineeringUnit = iter.value().sensorEngineeringUnit; + WaveDisplay.SamleRate = iter.value().SamleRate; + + //file.close(); + mapWaveDisplayData_RPM.insert(iter.key(),WaveDisplay); + } + } + qDebug() << " _RPM"<< mapWaveDisplayData_RPM.size() << endl; + QMap::Iterator iter1 = mapWaveDisplayData_RPM.begin(); + for (int i = 0; i < listChannelID.size(); ++i){ + for(iter1 = mapWaveDisplayData_RPM.begin();iter1 != mapWaveDisplayData_RPM.end();iter1++) + { + if(listChannelID.at(i) == iter1.key()){ + QCPGraph* graph = ui->widget->addGraph(); + ui->widget->graph(i)->setData(iter1.value().Key, iter1.value().wavedata); + ui->widget->graph(i)->rescaleValueAxis(); + ui->widget->graph(i)->setName(iter1.key()); + QPen pen; + pen.setColor(iter1.value().linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(i)->setPen(pen); + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + waveGraph.insert(iter1.key(),graph); + QString xAxis = ""; + xAxis = QString("Time(s) 平均转速:%1").arg(iter1.value().meanRpm); + ui->widget->xAxis->setLabel(xAxis); + ui->widget->yAxis->setLabel(iter1.value().channelType + "(" + iter1.value().sensorEngineeringUnit+")"); + } + } + } + ui->widget->xAxis->setRange(0, 1, Qt::AlignLeft); + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + ZoomBtnSlot_XY(); +} +void ChildForm::ToRpm() +{ + /*if(global::rotatingSpeed.iTriggerValue == 0 ||\ + global::rotatingSpeed.iKeyCount == 0 ||\ + global::rotatingSpeed.iHysteresis == 0) + { + MyMsgBox(QMessageBox::Question,"警告","请先设置转速参数!"); + return; + }*/ + + + if(listChannelID.size() > 1) + return; + qDebug() << global::rotatingSpeed.iTriggerValue << global::rotatingSpeed.iKeyCount \ + << global::rotatingSpeed.iHysteresis<< global::rotatingSpeed.iTrigger << endl; + ui->widget->clearGraphs(); + QMap().swap(waveGraph); + if(m_bRpm){ + m_bRpm = false; + handlePlayWave(m_position); + }else{ + m_bRpm = true; +// if(mapWaveDisplayData_RPM.size() == mapWaveDisplayData.size() && \ +// mapWaveDisplayData_RPM.size() > 0 /*&& \ +// _rotatingSpeed.iHysteresis == global::rotatingSpeed.iHysteresis && \ +// _rotatingSpeed.iTriggerValue == global::rotatingSpeed.iTriggerValue && \ +// _rotatingSpeed.iKeyCount == global::rotatingSpeed.iKeyCount && \ +// _rotatingSpeed.iTrigger == global::rotatingSpeed.iTrigger*/ ){ +// handlePlayWave(m_position); +// return; +// } + + CalculateRPM(); + } + +} +void ChildForm::ZoomBtnSlot_X() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + int graphCount = ui->widget->graphCount(); +// for(int i = 0; i < graphCount; i++){ +// ui->widget->graph(i)->rescaleKeyAxis(true); +// } + if(graphCount > 0){ + ui->widget->graph(0)->rescaleKeyAxis(); + for(int i = 1; i < graphCount; i++){ + ui->widget->graph(i)->rescaleKeyAxis(true); + } + + ui->widget->replot(); + } + ui->widget->replot(); +} +void ChildForm::ZoomBtnSlot_Y() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + int graphCount = ui->widget->graphCount(); +// for(int i = 0; i < graphCount; i++){ +// ui->widget->graph(i)->rescaleValueAxis(true); +// } + if(graphCount > 0){ + ui->widget->graph(0)->rescaleValueAxis(); + for(int i = 1; i < graphCount; i++){ + ui->widget->graph(i)->rescaleValueAxis(true); + } + + ui->widget->replot(); + } + ui->widget->replot(); +} +void ChildForm::ZoomBtnSlot_XY() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + int graphCount = ui->widget->graphCount(); + if(graphCount > 0){ + ui->widget->graph(0)->rescaleValueAxis(); + for(int i = 1; i < graphCount; i++){ + ui->widget->graph(i)->rescaleValueAxis(true); + } + + ui->widget->replot(); + } + +} +void ChildForm::ZoomBtnSlot_Hand() +{ + + + +// ui->widget->setMultiSelectModifier(Qt::ControlModifier);// 使用ctrl键来多选 +// ui->widget->xAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels); // 轴的三个部分都可以被选择 +// ui->widget->yAxis->setSelectableParts(QCPAxis::spAxis | QCPAxis::spAxisLabel | QCPAxis::spTickLabels); + +// ui->widget->legend->setSelectableParts(QCPLegend::spItems);// 图例本身不能被选择,只有里面的项可以被选择 +// ui->widget->legend->setSelectedIconBorderPen(Qt::NoPen);// 设置图例里的项被选择时不显示Icon的边框 + +// ui->widget->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine));//设置选框的样式:虚线 +// ui->widget->selectionRect()->setBrush(QBrush(QColor(0,0,100,50)));//设置选框的样式:半透明浅蓝 + +// ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);//被框选的曲线放大 + + + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + if(ui->zoomBtn_hand->isChecked()){ + //交互设置 + ui->widget->setInteractions(QCP::iRangeDrag | QCP::iSelectAxes | QCP::iSelectLegend | QCP::iMultiSelect); + //ui->widget->setInteractions(QCP::iRangeDrag); + }else if(!ui->zoomBtn_hand->isChecked()){ + ui->widget->setInteractions(QCP::iNone); + } +} +void ChildForm::Btn_ZoomSlot() +{ + if(ui->Btn_Zoom->isChecked()){ + ui->widget->setInteractions(QCP::iRangeDrag); + ui->widget->axisRect()->setRangeZoomFactor(1.2,1.2); + }else if(!ui->Btn_Zoom->isChecked()){ + ui->widget->setInteractions(QCP::iNone); + } + +} +void ChildForm::ScalesX() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + ui->widget->setInteractions(QCP::iRangeZoom|QCP::iRangeDrag); + ui->widget->axisRect()->setRangeZoomFactor(1.2,1); + + ui->widget->axisRect()->setRangeZoomAxes(ui->widget->xAxis,ui->widget->yAxis); +} +void ChildForm::ScalesY() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + ui->widget->setInteractions(QCP::iRangeZoom|QCP::iRangeDrag|QCP::iSelectAxes); + ui->widget->axisRect()->setRangeZoomFactor(1,1.2); + for(int i = 0; i < axes.size();i++){ + if (axes[i]->selectedParts().testFlag(QCPAxis::spAxis)) + ui->widget->axisRect()->setRangeZoomAxes(ui->widget->xAxis,axes[i]); + } + //ui->widget->axisRect()->setRangeZoomAxes(ui->widget->xAxis,ui->widget->yAxis); +} +void ChildForm::ScalesXY() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmNone); + ui->widget->setInteractions(QCP::iRangeZoom|QCP::iRangeDrag|QCP::iSelectAxes); + ui->widget->axisRect()->setRangeZoomFactor(1.2,1.2); + for(int i = 0; i < axes.size();i++){ + if (axes[i]->selectedParts().testFlag(QCPAxis::spAxis)) + ui->widget->axisRect()->setRangeZoomAxes(ui->widget->xAxis,axes[i]); + } + //ui->widget->axisRect()->setRangeZoomAxes(ui->widget->xAxis,ui->widget->yAxis); +} +void ChildForm::ScalesBox() +{ + ui->widget->setSelectionRectMode(QCP::SelectionRectMode::srmZoom); + ui->widget->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine));//虚线 + ui->widget->selectionRect()->setBrush(QBrush(QColor(255, 222, 173,50)));//NavajoWhite +} +void ChildForm::Cursor() +{ + ui->widget->setInteractions(QCP::iRangeZoom|QCP::iRangeDrag); + dismove = connect(ui->widget, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoveEvent(QMouseEvent*))); + disDoubleclick = connect(ui->widget, SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(mouseDoubleClickEvent(QMouseEvent*))); + disPress = connect(ui->widget, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheelEvent(QWheelEvent*))); +} +void ChildForm::SetScales() +{ + pSetScales = new SetScalesForm(this); //将类指针实例化 + connect(pSetScales, SIGNAL(sgSetScales(QString)), this, SLOT(slotSetScales(QString))); + pSetScales->setWindowModality(Qt::ApplicationModal); + pSetScales->show(); + +} +void ChildForm::slotSetScales(QString str) +{ + QStringList strList = str.split(","); + qDebug() << "slotSetScales" << strList[2].toFloat()<widget->xAxis->setRange(strList[0].toFloat(), strList[1].toFloat()-strList[0].toFloat(), Qt::AlignLeft); + for(int i = 0; i < axes.size();i++){ + if (axes[i]->selectedParts().testFlag(QCPAxis::spAxis)) + axes[i]->setRange(strList[2].toFloat(), strList[3].toFloat()-strList[2].toFloat(), Qt::AlignLeft); + } + + ui->widget->replot(QCustomPlot::rpImmediateRefresh); +} +void ChildForm::slotSetFilter(QString str) +{ + QStringList strList = str.split(","); + UpdateEnvSerises(strList[0],strList[1]); +} +void ChildForm::SetFilter() +{ + pSetFilter = new FilterForm(this); //将类指针实例化 + connect(pSetFilter, SIGNAL(sgSetFilter(QString)), this, SLOT(slotSetFilter(QString))); + pSetFilter->setWindowModality(Qt::ApplicationModal); + pSetFilter->show(); + +} + +void ChildForm::RealTimeWave(QByteArray payLoad) +{ + + WAVE_CONTAIN waveContain; + char *buf; + buf = payLoad.data(); + qDebug() << "payLoad.len" << payLoad.length() << endl; + for(int i = 0; i < listChannelID.size();i++){ + + memcpy(&waveContain,buf + (i*sizeof (WAVE_CONTAIN)),sizeof(WAVE_CONTAIN)); + qDebug() << "channelId"< vecRealTimeWave; + + // QString filename = QString("e://RealTime.csv"); + // QFile file(filename); + // qDebug()<< "filename = "<::Iterator iter = waveGraph.begin(); + for(;iter != waveGraph.end();iter++){ + if(iter.key() == QString(waveContain.channelId)){ + ui->widget->removeGraph(iter.value()); + waveGraph.erase(iter); + } + } + + QMap>::Iterator iterWave = mapWaveData.begin(); + for(;iterWave != mapWaveData.end();iterWave++){ + if(iterWave.key() == QString(waveContain.channelId)){ + iterWave.value()[m_position].waveDataRealTime = vecRealTimeWave; + iterWave.value()[m_position].SamleRateRealTime = waveContain.number; + break; + } + } + + QCPGraph* graph = NULL; + WAVE_DISPALYDATA waveShowData; + QMap>::Iterator iterMultiAxis = mapMultiGraph.begin(); + for(;iterMultiAxis != mapMultiGraph.end();iterMultiAxis++){ + QMap::Iterator iterAxis = iterMultiAxis.value().begin(); + for(;iterAxis != iterMultiAxis.value().end();iterAxis++){ + if(iterAxis.key() == QString(waveContain.channelId)){ + qDebug() << iterAxis.key() << endl; + SecondData(iterAxis.key(),iterWave.value()[m_position],waveShowData); + graph = ui->widget->addGraph(ui->widget->xAxis,iterAxis.value()); + iterAxis.value()->setLabel(waveShowData.channelType + "(" + waveShowData.sensorEngineeringUnit+")"); + if(m_iFormType == TimeDomainPlot){ + //if(iterWave.value()[m_position].sensorType == "ACCELEROMETER" || iterWave.value()[m_position].sensorType == "MICROPHONE") + { + if(m_bDC) + graph->setData(waveShowData.Key, waveShowData.wavedata_DC); + else + graph->setData(waveShowData.Key, waveShowData.wavedata); + } + }else if(m_iFormType == FrequencyDomainPlot){ + graph->setData(waveShowData.Key, waveShowData.wavedata); + } + + } + } + } + graph->rescaleValueAxis(); + graph->setName(waveShowData.channleName); + QPen pen; + pen.setColor(waveShowData.linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + graph->setPen(pen); + if(m_iFormType == FrequencyDomainPlot || m_iFormType == EnvChartPlot){ + ui->widget->xAxis->setRange(0, 1000); + } + + waveGraph.insert(QString(waveContain.channelId),graph); + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + } + +} + +void ChildForm::PlaySoundThread() +{ + ui->widget->clearGraphs(); + PaStreamParameters outputParameters; + PaStream *stream; + PaError err; + QVector f; + int SAMPLE_RATE = 0; + +// int NUM_SECONDS = 0; +// int FRAMES_PER_BUFFER = 1024; + int NUM_SECONDS = 0; + int bufferCount = 0; + int count = 0; + int a,b; + float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */ + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + if (outputParameters.device == paNoDevice) { + fprintf(stderr,"Error: No default output device.\n"); + goto error; + } + outputParameters.channelCount = 2; /* stereo output */ + outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ + outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; // Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + + for(int i = 0; i < listChannelID.size();i++){ + QMap>::Iterator iterWaveData = mapWaveData.begin(); + for(;iterWaveData != mapWaveData.end();iterWaveData++){ + if(listChannelID[i] == iterWaveData.key()){ + SAMPLE_RATE = iterWaveData.value()[0].SamleRate; + NUM_SECONDS = iterWaveData.value().size(); + for(int ii = 0; ii < iterWaveData.value().size();ii++){ + for(int j = 0 ; j < iterWaveData.value()[ii].waveData.size(); j++){ + + f.push_back((iterWaveData.value()[ii].waveData[j]-iterWaveData.value()[ii].mean)/1000); + } + } + } + } + } + qDebug() << "f" << f.size() << endl; + + err = Pa_OpenStream( + &stream, + NULL, /* no input */ + &outputParameters, + SAMPLE_RATE, + 1024, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, /* no callback, use blocking API */ + NULL ); /* no callback, so no callback userData */ + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + qDebug()<<"NUM_SECONDS " << NUM_SECONDS << endl; + + bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER); + + + qDebug()<<"bufferCount " << bufferCount << endl; + for(a =0; a < bufferCount; a++ ) + { + if(m_isStop) + break; + for(b =0; b < FRAMES_PER_BUFFER; b++ ) + { + count = b + a*FRAMES_PER_BUFFER; + buffer[b][0] = f[count]; /* left */ + buffer[b][1] = f[count]; /* right */ + } + + err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER ); + if( err != paNoError ) goto error; + if( ((a+1) * FRAMES_PER_BUFFER % SAMPLE_RATE == 0)){ + emit PlayWaveSig(); + } + std::unique_lock lock(mu); + m_cv.wait(lock, [this] {return !m_isPause; }); + } + qDebug()<<"count " << count << endl; + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + Pa_Sleep( 1000 ); + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + + Pa_Terminate(); + printf("Test finished.\n"); + ui->Btn_Sound->setChecked(false); + EnableBtn(); +error: + fprintf( stderr, "An error occurred while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + // Print more information about the error. + if( err == paUnanticipatedHostError ) + { + const PaHostErrorInfo *hostErrorInfo = Pa_GetLastHostErrorInfo(); + fprintf( stderr, "Host API error = #%ld, hostApiType = %d\n", hostErrorInfo->errorCode, hostErrorInfo->hostApiType ); + fprintf( stderr, "Host API error = %s\n", hostErrorInfo->errorText ); + } + Pa_Terminate(); + qDebug() << "PlayWaveSound end" << endl; + ui->Btn_Sound->setChecked(false); + EnableBtn(); + +} + +void ChildForm::OnPlayWaveSound() +{ + qDebug() << "PlayWaveSound" << endl; + QMap::Iterator iter1 = mapWaveDisplayData.begin(); + for(iter1 = mapWaveDisplayData.begin();iter1 != mapWaveDisplayData.end();iter1++){ + qDebug() << iter1.value().channelType << endl; + if(iter1.value().channelType == "ACCELEROMETER" || iter1.value().channelType == "MICROPHONE"){ + + }else{ + MyMsgBox(QMessageBox::Warning,"警告","支持加速度和声音通道进行播放!"); + ui->Btn_Sound->setChecked(false); + return; + } + } + if(!ui->Btn_Sound->isChecked()){ + ui->Btn_Sound->setChecked(false); + std::unique_lock lock(mu); + m_isPause = true; + m_cv.notify_one(); + return; + } + + if(m_isPause){ + std::unique_lock lock(mu); + m_isPause = false; + m_cv.notify_one(); + return; + } + + if(listChannelID.size() > 2) + return; + + EnableBtn(); + emit InitWaveSig(); + m_isStop = false; +// m_pPlaySound = new PlayWaveSound(); +// m_pThread = new QThread; +// //移动到另一线程 +// m_pPlaySound->moveToThread(m_pThread); +// m_pThread->start(); +// QCoreApplication::processEvents(); + + std::thread t1(&ChildForm::PlaySoundThread,this); + t1.detach(); + +} + +void ChildForm::realTimeData() +{ + + QString topicPub = QString("up/%1/recive/waveserver").arg(m_DeviceInfo->DeviceMac);//推送 + QString topicSub = QString("up/%1/waveserver").arg(m_DeviceInfo->DeviceMac);//订阅 + + QJsonArray channel_Arr; + QJsonObject root_Obj; + QJsonObject item_Obj; + for(int i = 0; i < listChannelID.size();i++){ + item_Obj.insert("channelId",listChannelID[i]); + item_Obj.insert("flag",1); + channel_Arr.insert(i,item_Obj); + } + root_Obj.insert("cmd","09"); + if(!m_bRealTime){ + m_bRealTime = true; + root_Obj.insert("type","GET"); + }else{ + root_Obj.insert("type","STOP"); + m_bRealTime = false; + //handlePlayWave(m_position); + } + root_Obj.insert("channelArray",channel_Arr); + QJsonDocument root_Doc; + root_Doc.setObject(root_Obj); + QByteArray root_str = root_Doc.toJson(QJsonDocument::Compact); + QString strJson(root_str); + qDebug() << strJson << endl; + QMQTT::Message message(136,topicPub,strJson.toUtf8()); + mqttclient->Push(message); + mqttclient->subscribed(topicSub); + connect(mqttclient, SIGNAL(WaveData_sig(QByteArray)), this, SLOT(RealTimeWave(QByteArray))); + EnableBtn(); +} + + +void ChildForm::SetDC() +{ + QMap>::iterator iter = mapMultiGraph.begin(); + for(;iter != mapMultiGraph.end();iter ++){ + if(iter.key() == "VELOCITY" || iter.key() == "MICROPHONE" || iter.key() == "ACCELEROMETER" ){ + MyMsgBox(QMessageBox::Warning,"警告","加速度、速度信号、声音信号只有AC数据"); + if(ui->Btn_AC_DC->isChecked()){ + ui->Btn_AC_DC->setChecked(false); + ui->Btn_AC_DC->setEnabled(false); + } + return; + } + } + + int graphCount = ui->widget->clearGraphs(); + QMap().swap(waveGraph); + qDebug() << "graphCount" << graphCount<< endl; + + if(!ui->Btn_AC_DC->isChecked()){ + m_bDC = false; + }else if(ui->Btn_AC_DC->isChecked()){ + m_bDC = true; + } + handlePlayWave(m_position); +} + +void ChildForm::CalculateIntegration(bool isDoubleIntegration) +{ + ui->widget->clearGraphs(); + QMap().swap(waveGraph); + QVector x,y,y1,realvalue,imagevalue; + QVector temDCWave; + QVector temHanning; + QVector AddHanning; + QVector realshiftfft; + QVector imageshiftfft; + QVector ifft; + QMap::Iterator iter = mapWaveDisplayData.begin(); + for (int i = 0; i < listChannelID.size(); ++i){ + for(;iter != mapWaveDisplayData.end();iter++){ + if(listChannelID.at(i) == iter.key()){ + QVector().swap(x); + QVector().swap(y); + QVector().swap(realvalue); + QVector().swap(imagevalue); + QVector().swap(temDCWave); + QVector().swap(realshiftfft); + QVector().swap(imageshiftfft); + for(int j = 0; j < iter.value().SamleRate;j++){ + temDCWave.push_back(iter.value().wavedata.at(j) - iter.value().mean); + } + pCalculation->_FFT(temDCWave,realshiftfft,imageshiftfft); + + for (int i = 0; i < 10; i++) { + realshiftfft[i] = 0; + imageshiftfft[i] = 0; + } + for (int i = 1000; i < realshiftfft.size(); i++) { + realshiftfft[i] = 0; + imageshiftfft[i] = 0; + } + qDebug()<< realshiftfft.size() << endl; + qDebug()<< imageshiftfft.size() << endl; + + for(int k = 1; k < realshiftfft.size()+1;k++){ + //qDebug()<< k << endl; + //x.push_back(k - 1); + realvalue.push_back((realshiftfft.at(k-1)/(k*2*3.14))*1000);//单位转换mm/s,*1000 + imagevalue.push_back((imageshiftfft.at(k-1)/(k*2*3.14))*1000);//单位转换mm/s,*1000 + } + double f = 0.0; + + pCalculation->_iFFT(realvalue,imagevalue,y); + if(isDoubleIntegration){ + m_bDoubleIntegration = true; + qDebug() << "DoubleIntegration" << endl; + QVector realshiftfft2; + QVector imageshiftfft2; + QVector key,Proximeter,realvalue2,imagevalue2; + pCalculation->_FFT(y,realshiftfft2,imageshiftfft2); + qDebug()<< "imageshiftfft2" <_iFFT(realvalue2,imagevalue2,Proximeter); + qDebug()<< "Proximeter" << Proximeter.size() << endl; + double gap = (double)1/(double)Proximeter.size(); + for(int ii = 0; ii < Proximeter.size();ii++){ + f += gap; + key.push_back(f); + } + qDebug()<< "key" <widget->xAxis->setRange(0, 1); + QCPGraph* graph = ui->widget->addGraph(); + ui->widget->graph(i)->setData(key, Proximeter); + // let the ranges scale themselves so graph 0 fits perfectly in the visible area: + ui->widget->graph(i)->rescaleValueAxis(); + QPen pen; + pen.setColor(iter.value().linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(i)->setPen(pen); + // give the axes some labels: + ui->widget->xAxis->setLabel("Time(s)"); + if(iter.value().channelType =="ACCELEROMETER"){ + ui->widget->yAxis->setLabel("PROXIMETER(um)"); + } + waveGraph.insert(listChannelID.at(i), graph); + + }else{ + double gap = (double)1/(double)y.size(); + for(int ii = 0; ii < y.size();ii++){ + f += gap; + x.push_back(f); + } + ui->widget->xAxis->setRange(0, 1); + QCPGraph* graph = ui->widget->addGraph(); + ui->widget->graph(i)->setData(x, y); + // let the ranges scale themselves so graph 0 fits perfectly in the visible area: + ui->widget->graph(i)->rescaleValueAxis(); + QPen pen; + pen.setColor(iter.value().linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(i)->setPen(pen); + // give the axes some labels: + ui->widget->xAxis->setLabel("Time(s)"); + if(iter.value().channelType =="VELOCITY"){ + ui->widget->yAxis->setLabel("PROXIMETER(um)"); + }else if(iter.value().channelType =="ACCELEROMETER"){ + ui->widget->yAxis->setLabel("Velocity(mm/s)"); + } + waveGraph.insert(listChannelID.at(i), graph); + } + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + + } + + } + } +} + +void ChildForm::CalculateDifferentiation(bool isDoubleDifferentiation) +{ + QVector key,value,yValue,key2,yValue2; + QMap::Iterator iter = mapWaveDisplayData.begin(); + for (int i = 0; i < listChannelID.size(); ++i){ + for(;iter != mapWaveDisplayData.end();iter++){ + if(listChannelID.at(i) == iter.key()){ + double gap,f; + f= 0; + gap = (double)1/(double)iter.value().SamleRate; + + value.push_back(iter.value().wavedata.at(0) - iter.value().mean); + for(int j = 1; j < iter.value().SamleRate-3;j++) + { + value.push_back((iter.value().wavedata.at(j+1)-iter.value().wavedata.at(j-1))/(double)(2*1/(double)iter.value().SamleRate)); + } + value.push_back(iter.value().wavedata.at(iter.value().SamleRate-1) - iter.value().mean); + + for(int i = 0 ; i < value.size();i++){ + yValue.push_back(value[i]/(double)10000); + f += gap; + key.push_back(f); + } + + QCPGraph* graph = ui->widget->addGraph(); + + if(isDoubleDifferentiation){//二次微分 + m_bDoubleDifferentiation = true; + QVector().swap(value); + f = 0; + value.push_back(yValue[0]); + for(int jj = 1; jj < yValue.size()-3;jj++) + { + value.push_back((yValue.at(jj+1)-yValue.at(jj-1))/(double)(2*1/(double)iter.value().SamleRate)); + } + value.push_back(yValue[yValue.size()-1]); + + for(int i = 0 ; i < value.size();i++){ + yValue2.push_back(value[i]/(double)10000); + f += gap; + key2.push_back(f); + } + ui->widget->xAxis->setRange(0, 1); + ui->widget->graph(i)->setData(key2, yValue2); + ui->widget->yAxis->setLabel("ACCELEROMETER(m/s^2)"); + }else{ + ui->widget->xAxis->setRange(0, 1); + ui->widget->graph(i)->setData(key, yValue); + ui->widget->yAxis->setLabel("Velocity(mm/s)"); + } + + waveGraph.insert(listChannelID.at(i), graph); + // let the ranges scale themselves so graph 0 fits perfectly in the visible area: + ui->widget->graph(i)->rescaleValueAxis(); + QPen pen; + pen.setColor(iter.value().linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(i)->setPen(pen); + // give the axes some labels: + ui->widget->xAxis->setLabel("Frequency(Hz)"); + + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + } + } + } + +} +void ChildForm::DoubleDifferentiationSlot() +{ + qDebug() << "DoubleDifferentiationSlot" << endl; + + if(listChannelID.size() > 1) + return; + ui->widget->clearGraphs(); + if(m_bDoubleDifferentiation){ + m_bDoubleDifferentiation = false; + handlePlayWave(m_position); + }else{ + m_bDoubleDifferentiation = true; + m_bDifferentiation = false; + if(m_iFormType == TimeDomainPlot){ + CalculateDifferentiation(true); + } + } +} +void ChildForm::DifferentiationSlot() +{ + qDebug() << "differentiationSlot" << endl; + + if(listChannelID.size() > 1) + return; + ui->widget->clearGraphs(); + if(m_bDifferentiation){ + m_bDifferentiation = false; + handlePlayWave(m_position); + }else{ + m_bDifferentiation = true; + m_bDoubleDifferentiation = false; + if(m_iFormType == TimeDomainPlot){ + CalculateDifferentiation(); + } + } +} + +void ChildForm::DoubleIntegrationSlot(){ + + qDebug() << "DoubleIntegrationSlot" << endl; + if(listChannelID.size() > 1) + return; + ui->widget->clearGraphs(); + if(m_bDoubleIntegration){ + m_bDoubleIntegration = false; + handlePlayWave(m_position); + }else{ + m_bDoubleIntegration = true; + m_bIntegration = false; + if(m_iFormType == TimeDomainPlot){ + CalculateIntegration(true); + } + } +} + +void ChildForm::IntegrationSlot() +{ + if(listChannelID.size() > 1) + return; + ui->widget->clearGraphs(); + if(m_bIntegration){ + m_bIntegration = false; + handlePlayWave(m_position); + }else{ + m_bIntegration = true; + m_bDoubleIntegration = false; + QVector x,y,y1,realvalue,imagevalue; + QVector temDCWave; + QVector temHanning; + QVector AddHanning; + QVector realshiftfft; + QVector imageshiftfft; + QVector ifft; + if(m_iFormType == TimeDomainPlot){ + CalculateIntegration(); + }else if(m_iFormType == FrequencyDomainPlot){ + QMap::Iterator iter = mapWaveDisplayData.begin(); + for (int i = 0; i < listChannelID.size(); ++i){ + for(;iter != mapWaveDisplayData.end();iter++){ + if(listChannelID.at(i) == iter.key()){ + QVector().swap(x); + QVector().swap(y); + QVector().swap(realvalue); + QVector().swap(imagevalue); + QVector().swap(temDCWave); + QVector().swap(realshiftfft); + QVector().swap(imageshiftfft); + for(int j = 0; j < iter.value().SamleRate;j++){ + temDCWave.push_back(iter.value().wavedata.at(j) - iter.value().mean); + } + //pCalculation->_FFT(temDCWave,realshiftfft,imageshiftfft); + pCalculation->FFTSpec(temDCWave,realshiftfft); + for (int i = 0; i < 10; i++) { + realshiftfft[i] = 0; + } + for (int i = 1000; i < realshiftfft.size(); i++) { + realshiftfft[i] = 0; + } + + + for(int k = 1; k < realshiftfft.size()+1;k++){ + x.push_back(k - 1); + realvalue.push_back(realshiftfft.at(k-1)/(k*2*3.14)*1000); + } + ui->widget->xAxis->setRange(0, realvalue.size()); + ui->widget->addGraph(); + ui->widget->graph(i)->setData(x, realvalue); + // let the ranges scale themselves so graph 0 fits perfectly in the visible area: + ui->widget->graph(i)->rescaleValueAxis(); + QPen pen; + pen.setColor(iter.value().linColor); + pen.setStyle(Qt::SolidLine); + pen.setWidth(0); + ui->widget->graph(i)->setPen(pen); + // give the axes some labels: + ui->widget->xAxis->setLabel("Frequency(Hz)"); + ui->widget->yAxis->setLabel("Velocity(mm/s)"); + ui->widget->replot(QCustomPlot::rpImmediateRefresh); + } + + } + + } + } + } + ui->widget->replot(QCustomPlot::rpImmediateRefresh); +} + +void ChildForm::EnableBtn() +{ + if(m_iFormType == TimeDomainPlot){ + if(ui->Btn_Sound->isChecked()){ + ui->Btn_Zoom->setEnabled(false); + ui->Btn_ZoomMenu->setEnabled(false); + ui->Btn_setScales->setEnabled(false); + ui->measureBtn->setEnabled(false); + ui->Btn_Hz->setEnabled(false); + ui->Btn_AC_DC->setEnabled(false); + ui->Btn_differentiation->setEnabled(false); + ui->temBtn_4->setEnabled(false); + ui->temBtn_5->setEnabled(false); + ui->Btn_Cursor->setEnabled(false); + ui->Btn_Annotation->setEnabled(false); + ui->realTimeDataBtn->setEnabled(false); + }else if(ui->realTimeDataBtn->isChecked()){ + ui->zoomBtn_hand->setEnabled(false); + ui->Btn_Zoom->setEnabled(false); + ui->Btn_ZoomMenu->setEnabled(false); + ui->Btn_setScales->setEnabled(false); + ui->measureBtn->setEnabled(false); + ui->Btn_Hz->setEnabled(false); + ui->Btn_AC_DC->setEnabled(false); + ui->Btn_differentiation->setEnabled(false); + ui->temBtn_4->setEnabled(false); + ui->temBtn_5->setEnabled(false); + ui->Btn_Cursor->setEnabled(false); + ui->Btn_Annotation->setEnabled(false); + ui->Btn_Sound->setEnabled(false); + }else{ + ui->zoomBtn_hand->setEnabled(true); + ui->Btn_Zoom->setEnabled(true); + ui->Btn_ZoomMenu->setEnabled(true); + ui->Btn_setScales->setEnabled(true); + ui->Btn_AC_DC->setEnabled(true); + ui->Btn_differentiation->setEnabled(true); + ui->Btn_Cursor->setEnabled(true); + ui->realTimeDataBtn->setEnabled(true); + ui->Btn_Sound->setEnabled(true); + } + } +} +//选点处理函数 +void ChildForm::OnPlotClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) +{ + //先获取点击的绘图层名称,然后通过名称找到图层ID,再找到对应的数据点 + int graphId = 0; + const QCPGraphData *ghd = ui->widget->graph(graphId)->data()->at(dataIndex); + qDebug() << ghd->key << ghd->value; +} + diff --git a/ChaosDataPlayer/ChildForm.h b/ChaosDataPlayer/ChildForm.h new file mode 100644 index 0000000..68234a4 --- /dev/null +++ b/ChaosDataPlayer/ChildForm.h @@ -0,0 +1,252 @@ +#ifndef CHILDFORM_H +#define CHILDFORM_H + +#include +#include "BaseWgt.h" +#include +#include +#include +#include +#include +#include "ChartView.h" +#include "global.h" +#include +#include "Calculation.hpp" +#include "qcustomplot.h" +#include "SetScalesform.h" +#include "FilterForm.h" +#include "Mqttclient.h" +#include "PlayWaveSound.h" + + +enum FormType +{ + TimeDomainPlot, //时域图 + FrequencyDomainPlot, //频域图 + TrendChartPlot, //趋势图 + SpecChartPlot, //频谱图 + EnvChartPlot, //包络图 + WaterFallPlot, //瀑布图 + OrbitPlot, //轴心轨迹 + PolarPlot, //极坐标 + BodePlot, //伯德图 + ShaftCenterline, //轴心位置图 + AllWavePlot //全谱图 +}; + + +typedef struct { + int key1; + int key2; + float fSpeed; +}RPM; +typedef struct _ChannelData +{ + QString ChannelId; +}ChannelData; + +class ChartView; +class Chart; +class QAbstractAxis; +class LegendForm; + +namespace Ui { +class ChildForm; +} +class ChildForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit ChildForm(FormType iType,QString m_strName = "",DEVICE_INFO* DeviceInfo = NULL, QWidget *parent = nullptr); + ~ChildForm(); + + void SetName(QString strName) + { + m_strName = strName; + } + + QString GetName() + { + return m_strName; + } + QHBoxLayout *pLayout; + Calculation *pCalculation; + QMetaObject::Connection dismove; + QMetaObject::Connection disDoubleclick; + QMetaObject::Connection disPress; + QMetaObject::Connection dis1; + WAVE_DATA m_waveData; + FormType m_iFormType; + void InitDisPaly(); + void InitRpmDisPaly(); + void ShowCharts(); + void SetFormType(FormType iType) {m_iFormType = iType;} + FormType GetFormType() { return m_iFormType;} + void SetWaveData(QString strID, QVector& waveData); + void SetDataIDs(const QStringList &strIDList, QString strTitle,const QStringList& strChannleTypeList,\ + const QStringList& strChannleNameList); + void handlePlayWave(double position = 0,double size = 131072); // + void AddOrbitSeries(QString strID, const QVector& wavexData,const QVector& waveyData,\ + const QVector& waveSpeedData); + void AddBodeSeries(QString strID, const QVector& wavexData,const QVector& waveSpeedData); + void AddShaftCenterlineSeries(QString strID, const QVector& wavexData,const QVector& waveData); + void AddPolarPlotSeries(QString strID, const QVector& wavexData,const QVector& waveSpeedData); + void UpdateEnvSerises(QString Start,QString End); + QPixmap GetSerise(QString& strImagePath); + void AddSeries(QString strID, QVector& waveData); + QCPGraph* MultiyAxis(QString strID,QString sensorType,QString sensorEngineeringUnit); + void SecondData(const QString& strID,WAVE_DATA& waveData,WAVE_DISPALYDATA& waveShowData); + void CalculateRPM(); + void CalculateIntegration(bool isDoubleIntegration = false); + void CalculateDifferentiation(bool isDoubleDifferentiation = false); + void EnableBtn(); + void UpdateDiffMenu(); + QVector childWave; + QVector OrbitXWave,OrbitYWave; + QVector vecKeyPhasor; + QList listChannelID; + QCPGraph *mainGraph1,*mainGraph2,*keyPhasor; + QCPCurve *fermatSpiral1; + QCPAxisRect *wideAxisRect1; + QCPAxisRect *wideAxisRect2; + QCPAxisRect *wideAxisRectOrbit; + QMap> mapBodeData; + + PlayWaveSound *m_pPlaySound; + QThread *m_pThread; +signals: + void ItemCheckStateSignal(QString strID, bool bChecked); + void OutSig(); + void ReturnSig(); + void PlayWaveSig(); + void InitWaveSig(); + +protected: + +public slots: + void ZoomBtnSlot_X(); + void ZoomBtnSlot_Y(); + void ZoomBtnSlot_XY(); + void ZoomBtnSlot_Hand(); + void ToRpm(); + void Btn_ZoomSlot(); + void IntegrationSlot(); + void DoubleIntegrationSlot(); + void DifferentiationSlot(); + void DoubleDifferentiationSlot(); + void ScalesBox(); + void ScalesX(); + void ScalesY(); + void ScalesXY(); + void Cursor(); + void SetScales(); + void SetFilter(); + void SetDC(); + void realTimeData(); + void mouseMoveEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void mouseWheelEvent(QWheelEvent *event); + void ChannelBtnSlot(); + void ItemChangedSlot(QTableWidgetItem *item); + void ItemPressSlot(QTableWidgetItem *item); + void slotSetScales(QString str); + void slotSetFilter(QString str); + void OnPlotClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void RealTimeWave(QByteArray payLoad); + void OnPlayWaveSound(); + void PlaySoundThread(); + +private: + bool m_bDC; + bool m_bRpm; + bool m_bIntegration; + bool m_bDifferentiation; + bool m_bDoubleIntegration; + bool m_bDoubleDifferentiation; + bool m_isPause; + bool m_isStop; + std::condition_variable m_cv; + std::mutex mu; + WAVE_CSVDATA m_vecCsvData[32]; + + int m_nStart; + int m_nEnd; + QMenu *remove_menu; + QAction *remove_selected_action; + QAction *remove_all_action; + QAction *Hz; + QAction *Ord; + QAction *Rad; + + QCPAxis *yAxis3; + QList axes; + QCPItemTracer *tracer; //游标 + QCPItemTracer *tracer2; //游标 + + QMap maptracerLabel; + QCPItemText *tracerLabel; //游标标签 + QCPItemText *tracerLabel2; //游标标签 + + QCPItemText *tracerLabel3; //游标标签 + QCPItemText *tracerLabel4; //游标标签 + QCPItemText *tracerLabel5; //游标标签 + QCPItemText *tracerLabel6; //游标标签 + QCPItemText *tracerLabel7; //游标标签 + QCPItemText *tracerLabel8; //游标标签 + + QMap mapWaveDisplayData; + QMap mapWaveDisplayData_RPM; + QMap> mapWaveData; + QMap> waveTrendData; + QMap>> waveDataDC; + + QMap waveGraph; + QMap waveYAxis; + QList listChannelType; + QMap> mapMultiGraph; //<通道类型,<通道ID,Y轴>> + RotatingSpeed _rotatingSpeed; + QVector x,y; + SetScalesForm *pSetScales; + FilterForm *pSetFilter; + MqttClient *mqttclient; + void InitWidget(); + void ClearAllSerise(); + void ClearTable(); + void RemoveSeries(QString strID); + + int m_position; + QTableWidgetItem * AddTableWgtItem(QString strText, QString clolor, QString strID); + + QMenu *differentiationMenu; + QAction *Integration; + QAction *doubleIntegration; + QAction *differentiation; + QAction *doubleDifferentiation; + + +private: + Ui::ChildForm *ui; + int line ; + QString m_strName; + + ChartView *m_pChartView; + QChart *m_pChart; + QLineSeries *series; + QStringList m_listChannelID; + + + QMap m_mapChannelIDtoLabel; + + bool m_bAttach; + DEVICE_INFO *m_DeviceInfo; + LegendForm *m_pLegendForm; + QTimer *m_pTimer; + int m_iRealTimer; //实时数据定时器ID + QString m_sServer; // 服务器地址 + QString m_sEquipNo; // 终端号 + //QMqttClient *m_client; + bool m_isconnect; // 是否已连接服务器 + bool m_bRealTime; +}; +#endif // CHILDFORM_H diff --git a/ChaosDataPlayer/ChildForm.ui b/ChaosDataPlayer/ChildForm.ui new file mode 100644 index 0000000..2eb2749 --- /dev/null +++ b/ChaosDataPlayer/ChildForm.ui @@ -0,0 +1,1014 @@ + + + ChildForm + + + true + + + + 0 + 0 + 1175 + 436 + + + + Form + + + #Btn_ZoomMenu { border-image:url(:/images/images/imgModelAction/Zoom_xy.png) 1; } +#Btn_ZoomMenu:hover { border-image:url(:/images/images/imgModelAction/Zoom-xy-h.png) 1; } +#Btn_ZoomMenu:pressed { border-image:url(:/images/images/imgModelAction/Zoom-xy-p.png) 1; } +#Btn_ZoomMenu:checked { border-image:url(:/images/images/imgModelAction/Zoom_xy.png) 1; } +#Btn_ZoomMenu::menu-indicator{image:none;} + +#Btn_setScales { border-image:url(:/images/images/imgModelAction/setScales.png) 5; } +#Btn_setScales:hover { border-image:url(:/images/images/imgModelAction/setScales-h.png) 5; } +#Btn_setScales:pressed {border-image:url(:/images/images/imgModelAction/setScales-p.png) 5; } +#Btn_setScales:checked {border-image:url(:/images/images/imgModelAction/setScales.png) 5; } + +#Btn_Annotation { border-image:url(:/images/images/imgModelAction/Annotation1.png) 5; } +#Btn_Annotation:hover { border-image:url(:/images/images/imgModelAction/Annotation-h.png) 5; } +#Btn_Annotation:pressed {border-image:url(:/images/images/imgModelAction/Annotation-p.png) 5; } +#Btn_Annotation:checked {border-image:url(:/images/images/imgModelAction/Annotation-p.png) 5; } + +#Btn_Sound { border-image:url(:/images/images/imgModelAction/Sound-d.png) 5; } +#Btn_Sound:hover { border-image:url(:/images/images/imgModelAction/Sound-h.png) 5; } +#Btn_Sound:pressed {border-image:url(:/images/images/imgModelAction/Sound-p.png) 5; } +#Btn_Sound:checked {border-image:url(:/images/images/imgModelAction/Sound-p.png) 5; } + +#returnBtn{border-image:url(:/images/images/imgModelAction/344.png);} + +#label_title{color: #aac3cf;} + +#tableWidget +{ + background:transparent; + border-top: 2px solid #50707f; + +} + +#tableWidget::item +{ + height: 24px; + border-width: 1; +} +#tableWidget::item:hover +{ + border: none; +} +#tableWidget::item:selected +{ + border: none; + color:#ffa405; +} + +#ChannelBtn{border-image:url(:/images/images/showChannel.png);} + +#line_3{border-image:url(:/images/images/line.png);} +#line_4{border-image:url(:/images/images/line.png);} +#line_5{border-image:url(:/images/images/line.png);} +#line_6{border-image:url(:/images/images/line.png);} + + +#zoomBtn_X { border-image:url(:/images/images/imgModelAction/axisX.png) 5; } +#zoomBtn_X:hover { border-image:url(:/images/images/imgModelAction/axisX-h.png) 5; } +#zoomBtn_X:pressed {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } +#zoomBtn_X:checked {border-image:url(:/images/images/imgModelAction/axisX-p.png) 5; } + +#Btn_Zoom { border-image:url(:/images/images/imgModelAction/Zoom.png) 1; } +#Btn_Zoom:hover { border-image:url(:/images/images/imgModelAction/Zoom-h.png) 1; } +#Btn_Zoom:pressed {border-image:url(:/images/images/imgModelAction/Zoom-p.png) 1; } +#Btn_Zoom:checked {border-image:url(:/images/images/imgModelAction/Zoom.png) 1; } + +#zoomBtn_Y { border-image:url(:/images/images/imgModelAction/axisY.png) 5; } +#zoomBtn_Y:hover { border-image:url(:/images/images/imgModelAction/axisY-h.png) 5; } +#zoomBtn_Y:pressed {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } +#zoomBtn_Y:checked {border-image:url(:/images/images/imgModelAction/axisY-p.png) 5; } + +#zoomBtn_hand { border-image:url(:/images/images/imgModelAction/hand1.png) 5; } +#zoomBtn_hand:hover { border-image:url(:/images/images/imgModelAction/hand-h.png) 5; } +#zoomBtn_hand:pressed {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } +#zoomBtn_hand:checked {border-image:url(:/images/images/imgModelAction/hand-p.png) 5; } + + +#measureBtn { border-image:url(:/images/images/imgModelAction/measure-d.png) 5; } +#measureBtn:hover { border-image:url(:/images/images/imgModelAction/measure-h.png) 5; } +#measureBtn:pressed {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } +#measureBtn:checked {border-image:url(:/images/images/imgModelAction/measure-p.png) 5; } + +#realTimeDataBtn { border-image:url(:/images/images/imgModelAction/realTime.png) 5; } +#realTimeDataBtn:hover { border-image:url(:/images/images/imgModelAction/realTime-h.png) 5; } +#realTimeDataBtn:pressed {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } +#realTimeDataBtn:checked {border-image:url(:/images/images/imgModelAction/realTime-p.png) 5; } + +#Btn_differentiation { border-image:url(:/images/images/imgModelAction/arf-h.png) 1; } +#Btn_differentiation:hover { border-image:url(:/images/images/imgModelAction/arf-h.png) 1; } +#Btn_differentiation:pressed {border-image:url(:/images/images/imgModelAction/arf-p.png) 1; } +#Btn_differentiation:checked {border-image:url(:/images/images/imgModelAction/arf.png) 1; } +#Btn_differentiation::menu-indicator{image:none;} + +#Btn_Hz { border-image:url(:/images/images/imgModelAction/HZ-h.png) 1; } +#Btn_Hz:hover { border-image:url(:/images/images/imgModelAction/HZ-h.png) 1; } +#Btn_Hz:pressed { border-image:url(:/images/images/imgModelAction/hz-2.png) 1; } +#Btn_Hz:checked { border-image:url(:/images/images/imgModelAction/HZ.png) 1; } +#Btn_Hz::menu-indicator{image:none;} + +#Btn_AC_DC { border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } +#Btn_AC_DC:hover { border-image:url(:/images/images/imgModelAction/AC-h.png) 5; } +#Btn_AC_DC:pressed {border-image:url(:/images/images/imgModelAction/AC.png) 5; } +#Btn_AC_DC:checked { border-image:url(:/images/images/imgModelAction/DC.png) 5; } + + + + +#temBtn_4 { border-image:url(:/images/images/imgModelAction/lvbo-h.png) 5; } + +#temBtn_5 { border-image:url(:/images/images/imgModelAction/TDBC-h.png) 5; } +#temBtn_5:hover { border-image:url(:/images/images/imgModelAction/TDBC-h.png) 5; } +#temBtn_5:pressed {border-image:url(:/images/images/imgModelAction/TDBC-p.png) 5; } +#temBtn_5:checked {border-image:url(:/images/images/imgModelAction/TDBC-p.png) 5; } + +#Btn_Cursor { border-image:url(:/images/images/imgModelAction/gb1.png) 1; } +#Btn_Cursor:hover { border-image:url(:/images/images/imgModelAction/gb-h.png) 1; } +#Btn_Cursor:pressed {border-image:url(:/images/images/imgModelAction/gb-p.png) 1; } +#Btn_Cursor:checked {border-image:url(:/images/images/imgModelAction/gb.png) 1; } + +#Btn_Open { border-image:url(:/images/images/imgModelAction/Open.png) 1; } +#Btn_Open:hover { border-image:url(:/images/images/imgModelAction/Open_h.png) 1; } +#Btn_Open:pressed {border-image:url(:/images/images/imgModelAction/Open_p.png) 1; } +#Btn_Open:checked {border-image:url(:/images/images/imgModelAction/Open_p.png) 1; } + +#Btn_Close { border-image:url(:/images/images/imgModelAction/Close.png) 1; } +#Btn_Close:hover { border-image:url(:/images/images/imgModelAction/Close.png) 1; } +#Btn_Close:pressed {border-image:url(:/images/images/imgModelAction/Close_h.png) 1; } +#Btn_Close:checked {border-image:url(:/images/images/imgModelAction/Close.png) 1; } + + +#Btn_Integration { border-image:url(:/images/images/imgModelAction/Integration.png) 5; } + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 2 + + + 10 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 38 + + + + + 16777215 + 38 + + + + TextLabel + + + + + + + QAbstractItemView::AnyKeyPressed|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + + false + + + false + + + true + + + false + + + + 新建列 + + + + + 新建列 + + + + + + + + + + + 0 + + + 2 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 16 + 120 + + + + + 16 + 120 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + 0 + + + 5 + + + 10 + + + 10 + + + + + + 0 + 41 + + + + + 16777215 + 41 + + + + + + 90 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 自动缩放XY + + + + + + + + + true + + + + + + 600 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 最大化 + + + + + + + + + 10 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 移动 + + + + + + true + + + false + + + + + false + + + + 180 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + Y轴去对数 + + + + + + true + + + false + + + + + true + + + + 520 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 实时数据 + + + + + + true + + + false + + + + + false + + + + 220 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + X坐标变换 + + + + + + true + + + false + + + + + false + + + + 270 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 交流/直流 + + + + + + true + + + false + + + + + false + + + + 310 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 积分/微分 + + + + + + true + + + false + + + + + + 470 + 10 + 2 + 28 + + + + + 2 + 28 + + + + + 2 + 28 + + + + + + + + + false + + + + 350 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 滤波 + + + + + + true + + + false + + + + + false + + + + 390 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 跳动补偿 + + + + + + true + + + false + + + + + + 430 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 光标 + + + + + + true + + + false + + + + + + 50 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 聚焦 + + + + + + true + + + + + + 130 + 10 + 2 + 28 + + + + + 2 + 28 + + + + + 2 + 28 + + + + + + + + + + 140 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 设置坐标 + + + + + + true + + + + + + 260 + 10 + 2 + 28 + + + + + 2 + 28 + + + + + 2 + 28 + + + + + + + + + false + + + + 480 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 注解 + + + + + + true + + + false + + + + + false + + + + 560 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 播放声音 + + + + + + true + + + false + + + + + + 640 + 10 + 30 + 30 + + + + + 30 + 30 + + + + + 30 + 30 + + + + 最小化 + + + + + + Btn_Open + zoomBtn_hand + measureBtn + realTimeDataBtn + Btn_Hz + Btn_AC_DC + Btn_differentiation + line_4 + temBtn_4 + temBtn_5 + Btn_Cursor + Btn_Zoom + line_5 + Btn_ZoomMenu + Btn_setScales + line_6 + Btn_Annotation + Btn_Sound + Btn_Close + + + + + + true + + + background-color: rgb(0, 0, 0); + + + + + + + + + + QCustomPlot + QWidget +
qcustomplot.h
+ 1 +
+
+ + +
diff --git a/ChaosDataPlayer/CreateReport.cpp b/ChaosDataPlayer/CreateReport.cpp new file mode 100644 index 0000000..eb14382 --- /dev/null +++ b/ChaosDataPlayer/CreateReport.cpp @@ -0,0 +1,293 @@ +/******************************************************************** + created: 2018/03/27 + author: wangyuanyuan@vishee.com + edit_by: + description: 生成肌力训练报告 + +*********************************************************************/ + +#include "CreateReport.h" +#include +#include + +CreateReport::CreateReport() +{ + m_wordOperate = NULL; + + titleFontName = "SongTi"; + infoFontName = "Microsoft YaHei"; + tableFontName = "Microsoft YaHei"; + wordFontName = "Microsoft YaHei"; + + titleFontSize = 18; + infoFontSize = 11; + tableFontSize = 11; + wordFontSize = 9; + +} + +CreateReport::~CreateReport() +{ + ReleaseWord(); +} + +void CreateReport::GetReport(REPORT_INFO& reportInfo,QStringList& strImagePathList) +{ + _reportInfo = reportInfo; + _strImagePathList = strImagePathList; + if(!CreateWord()) + { + + } + +} + +bool CreateReport::CreateWord()//创建word +{ + qDebug() << "CreateWord" << endl; + if(InitWord() == false) + { + // LOG_ERROR("Init Word Failure"); + return false; + } + + SetPageMargin(); + m_wordOperate->SetVisible(false); + DrawTitle(); + DrawPatientInfo(); + //DrawTable(); + //DrawExplain(); + //DrawMark(); + //DrawPic(); + m_wordOperate->insertEnter(); + for(int i = 0; i < _strImagePathList.size();i++){ + qDebug() << _strImagePathList.at(i) << endl; + m_wordOperate->SetAlign(WordOperate::AlignmentTypeCenter); + m_wordOperate->InsertPicture(_strImagePathList.at(i)); + m_wordOperate->insertEnter(); + if(_strImagePathList.at(i).contains("TimeDomain")) + m_wordOperate->SetText("时域图"); + if(_strImagePathList.at(i).contains("FrequencyDomain")) + m_wordOperate->SetText("频域图"); + if(_strImagePathList.at(i).contains("TrendChart")) + m_wordOperate->SetText("趋势图"); + if(_strImagePathList.at(i).contains("EnvChart")) + m_wordOperate->SetText("包络图"); + m_wordOperate->insertEnter(); + } + DrawTable(); + m_wordOperate->SetVisible(true); + + return true; +} + +bool CreateReport::InitWord()//初始化word +{ + if(m_wordOperate == NULL) + m_wordOperate = new WordOperate(); + return m_wordOperate->open(false); +} + +void CreateReport::ReleaseWord()//释放word +{ + if(m_wordOperate != NULL) + { + m_wordOperate->close(); + delete m_wordOperate; + m_wordOperate = NULL; + } + +} + +void CreateReport::SetPageMargin()//设置边距 +{ + double dbLeft = 0.0,dbRight = 0.0,dbTop = 0.0,dbBottom = 0.0; + m_wordOperate->GetPageMargin(dbLeft,dbTop,dbRight,dbBottom); + m_wordOperate->SetPageMargin(dbLeft/2,dbTop/2,dbRight/2,dbBottom/2); +} + +void CreateReport::DrawTitle()//画标题 +{ + m_wordOperate->SetFont(titleFontName,titleFontSize,true); + m_wordOperate->SetAlign(WordOperate::AlignmentTypeCenter); + m_wordOperate->SetText("故障分析诊断报告"); + m_wordOperate->SetText("\n"); + /*m_wordOperate->SetFont(titleFontName,titleFontSize,true); + m_wordOperate->SetText(QStringLiteral("XXX\n"));*/ +} + +void CreateReport::DrawPatientInfo() +{ + int iLength=35; + m_wordOperate->SetAlign(WordOperate::AlignmentTypeLeft); + m_wordOperate->SetFont(infoFontName,infoFontSize,false); + QString str,temp; + QString strName,strSex,strAge,strDate,strCount,strTime; + str=QStringLiteral("终端名称:Data Watch"); + temp = _reportInfo.DeviceName; + str+=temp; + strName=QString("%1%2").arg(str).arg("\t",iLength-str.count()*2); + + iLength = 28; + str=QStringLiteral("终端MAC:"); + temp = _reportInfo.DeviceMac; + str+=temp; + strSex=QString("%1%2").arg(str).arg("\t",iLength-str.count()*2); + iLength = 15; + str=QStringLiteral("采集时间:"); + str+=_reportInfo.DevicemCollectTime; + strAge=QString("%1%2").arg(str).arg("\t",iLength-str.count()*2); + + str = strName+strSex+strAge; + m_wordOperate->SetText(str); + m_wordOperate->moveForEnd(); + + m_wordOperate->SetAlign(WordOperate::AlignmentTypeLeft); + m_wordOperate->SetFont(infoFontName,infoFontSize,false); + iLength = 35; + str = QString("%1").arg(QStringLiteral("报告时间:")); + + QDateTime current_date_time = QDateTime::currentDateTime(); + QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss"); + str = str + current_date; + m_wordOperate->SetText(str); + m_wordOperate->moveForEnd(); +} + +void CreateReport::DrawTable() +{ + // wps + int nTable=1; + m_wordOperate->SetAlign(WordOperate::AlignmentTypeCenter); + m_wordOperate->SetParagraphSpacing(WordOperate::SpaceExactly,30); + + m_wordOperate->SetFont(tableFontName,tableFontSize,false); + m_wordOperate->intsertTable(4,1); + m_wordOperate->SetTableRowHeight(nTable,2,200); + m_wordOperate->SetTableRowHeight(nTable,4,300); + + QAxObject *cell=NULL; + cell = m_wordOperate->setCellString(nTable,1,1,QStringLiteral("报告概述")); + cell = m_wordOperate->setCellString(nTable,3,1,QStringLiteral("详细报告")); + //m_wordOperate->insertCellPic(nTable, 4,1,"E://WorkSpace//QT//build-ChaosDataPlayer-Desktop_Qt_5_12_11_MinGW_32_bit-Release//release//report//standard.png"); + + /*m_wordOperate->MergeCell(nTable,1,1,1,3,true); + m_wordOperate->MergeCell(nTable,3,1,3,3,true); + m_wordOperate->SetTableRowHeight(nTable,3,300);*/ + + /*m_wordOperate->insertCellPic(nTable, 2,1,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + m_wordOperate->moveForEnd(); + m_wordOperate->insertCellPic(nTable, 2,1,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + m_wordOperate->moveForEnd(); + m_wordOperate->insertCellPic(nTable, 2,1,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + + QAxObject *cell=NULL; + cell = m_wordOperate->setCellString(nTable,1,1,QStringLiteral("诊断结果")); + cell = m_wordOperate->setCellString(nTable,2,1,QStringLiteral("时域图")); + cell = m_wordOperate->setCellString(nTable,2,2,QStringLiteral("频域图")); + cell = m_wordOperate->setCellString(nTable,2,3,QStringLiteral("包络图")); + m_wordOperate->insertCellPic(nTable, 2,1,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + m_wordOperate->insertCellPic(nTable, 2,2,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + m_wordOperate->insertCellPic(nTable, 2,3,"E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); + + /* m_wordOperate->SetTableFont(nTable,1,1,tableFontName,tableFontSize,true); + cell = m_wordOperate->setCellString(nTable,1,2,QStringLiteral("XX")); + m_wordOperate->SetTableFont(nTable,1,2,tableFontName,tableFontSize,true); + m_wordOperate->MergeCell(nTable,1,3,1,4,true); + cell = m_wordOperate->setCellString(nTable,1,3,QStringLiteral("XX")); + m_wordOperate->SetTableFont(nTable,1,3,tableFontName,tableFontSize,true); + cell = m_wordOperate->setCellString(nTable,1,4,QStringLiteral("XX")); + m_wordOperate->SetTableFont(nTable,1,4,tableFontName,tableFontSize,true); + + /*m_wordOperate->MergeCell(nTable,2,1,10,1,true); + cell= m_wordOperate->setCellString(nTable,2,1,QStringLiteral("XX")); + m_wordOperate->MergeCell(nTable,2,2,6,2,true); + m_wordOperate->setCellString(nTable,2,2,QStringLiteral("XX")); + m_wordOperate->MergeCell(nTable,2,3,4,3,true); + m_wordOperate->setCellString(nTable,2,3,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,5,3,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,6,3,QStringLiteral("XX")); + + m_wordOperate->MergeCell(nTable,7,2,10,2,true); + m_wordOperate->setCellString(nTable,7,2,QStringLiteral("XX")); + m_wordOperate->MergeCell(nTable,7,3,9,3,true); + m_wordOperate->setCellString(nTable,7,3,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,10,3,QStringLiteral("XX")); + + cell = m_wordOperate->setCellString(nTable,11,1,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,11,2,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,11,3,QStringLiteral("XX")); + + m_wordOperate->setCellString(nTable,2,4,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,3,4,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,4,4,QStringLiteral("XX")); + + m_wordOperate->setCellString(nTable,5,4,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,6,4,QStringLiteral("XX")); + + m_wordOperate->setCellString(nTable,7,4,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,8,4,QStringLiteral("XX")); + m_wordOperate->setCellString(nTable,9,4,QStringLiteral("XX")); + + m_wordOperate->setCellString(nTable,10,4,QStringLiteral("XX")); + + m_wordOperate->setCellString(nTable,11,4,QStringLiteral("XX"));*/ + + + } + +void CreateReport::DrawExplain() +{ + m_wordOperate->moveForEnd(); + m_wordOperate->SetFont(wordFontName,wordFontSize); + m_wordOperate->SetAlign(WordOperate::AlignmentTypeLeft); + m_wordOperate->SetParagraphSpacing(WordOperate::Space1); + QString str; + str = QStringLiteral("简要报告解读:"); + str += "\n"; + m_wordOperate->SetText(str); + m_wordOperate->SetFont(wordFontName,wordFontSize); + str = QStringLiteral("1、XXXXXXXX"); + str +="\n"; + m_wordOperate->SetText(str); + str = QStringLiteral("2、XXXXX。"); + str += "\n"; + + m_wordOperate->SetText(str); + str = QStringLiteral("3、XX。"); + str += "\n"; + + m_wordOperate->SetText(str); + + m_wordOperate->SetFont(wordFontName,wordFontSize); +} + +void CreateReport::DrawMark() +{ + //备注: + QString str; + m_wordOperate->moveForEnd(); + m_wordOperate->SetAlign(WordOperate::AlignmentTypeLeft); + m_wordOperate->SetFont(wordFontName,12,false,false,true); + str = QStringLiteral("备注:\n"); + m_wordOperate->SetText(str); + + m_wordOperate->SetFont(wordFontName,12,false,false,false); + m_wordOperate->intsertTable(2,1); + m_wordOperate->MergeCell(2,1,1,2,1); + m_wordOperate->setCellString(2,1,1,"xxx"); + + m_wordOperate->moveForEnd(); + m_wordOperate->SetAlign(WordOperate::AlignmentTypeLeft); + m_wordOperate->SetFont(wordFontName,11,false,false,false); + + str=QStringLiteral("xxx:"); + m_wordOperate->SetText(str); + m_wordOperate->SetFont(wordFontName,11,false,false,false); + m_wordOperate->SetText("____________________________"); + +} +void CreateReport::DrawPic() +{ + m_wordOperate->SetMarkPic("Pic1", "E://WorkSpace//QT//ChaosDataPlayerDemo//images//logo.png"); +} diff --git a/ChaosDataPlayer/CreateReport.h b/ChaosDataPlayer/CreateReport.h new file mode 100644 index 0000000..2145205 --- /dev/null +++ b/ChaosDataPlayer/CreateReport.h @@ -0,0 +1,50 @@ +/******************************************************************** + created: 2018/03/27 + author: wangyuanyuan@vishee.com + edit_by: + description: 生成训练报告 + +*********************************************************************/ + +#ifndef CREATREPORT_H +#define CREATEREPORT_H + +#include "WordOperate.h" +#include "global.h" + +class CreateReport +{ +public: + CreateReport(); + ~CreateReport(); +public: + void GetReport(REPORT_INFO& reportInfo,QStringList& strImagePathList); +private: + WordOperate *m_wordOperate; + QString hospitalName; + + bool CreateWord();//创建word + bool InitWord();//初始化word + void ReleaseWord();//释放word + void SetPageMargin();//设置边距 + void DrawTitle();//画标题 + void DrawPatientInfo(); + void DrawTable(); + void DrawMark(); + void DrawExplain(); + void DrawPic(); + + QString titleFontName; + QString infoFontName; + QString tableFontName; + QString wordFontName; + + double titleFontSize; + double infoFontSize; + double tableFontSize; + double wordFontSize; + + REPORT_INFO _reportInfo; + QStringList _strImagePathList; +}; +#endif // CREATEREPORT_H diff --git a/ChaosDataPlayer/DB/analyse.db b/ChaosDataPlayer/DB/analyse.db new file mode 100644 index 0000000..f8c1270 Binary files /dev/null and b/ChaosDataPlayer/DB/analyse.db differ diff --git a/ChaosDataPlayer/DataParsing.cpp b/ChaosDataPlayer/DataParsing.cpp new file mode 100644 index 0000000..c9f60f4 --- /dev/null +++ b/ChaosDataPlayer/DataParsing.cpp @@ -0,0 +1,81 @@ +#include "DataParsing.h" +#include + +DataParsing::DataParsing(QObject *parent) : QObject(parent) +{ + +} + +DataParsing::~DataParsing() +{ + +} + +void DataParsing::SetChannelSetting(const QString &str) +{ + QByteArray bytes = str.toLatin1(); + QJsonParseError jsonError; + QJsonDocument docunment = QJsonDocument::fromJson(bytes,&jsonError); + if (!docunment.isNull() && (jsonError.error == QJsonParseError::NoError)) + { + // qDebug() << "文件解析成功!"; + if(docunment.isObject()) //判断第一级对象是否存在 + { + QJsonObject objec = docunment.object(); + if(objec.contains("groups")) + { + QJsonValue arrays_value = objec.take("groups"); + if(arrays_value.isArray()) //判断它是不是json组 + { + QJsonArray array = arrays_value.toArray(); + int nsize = array.size(); + for(int i = 0; i< nsize; ++i)//groups + { + GroupData groupdata; + groupdata.ChannelType = array.at(i).toObject().value("ChannelType").toString(); + groupdata.Channelid = array.at(i).toObject().value("name").toString(); + if(array.at(i).toObject().value("channels").isArray()) + { + QJsonArray channelArray = array.at(i).toObject().value("channels").toArray(); + for(int i = 0;i < channelArray.size(); i++)//channels + { + //groupdata.mChannelData.clear(); + QString dataType = channelArray.at(i).toObject().value("name").toString(); + if(channelArray.at(i).toObject().value("data").isArray()) + { + QVector vec; + QJsonArray dataArray = channelArray.at(i).toObject().value("data").toArray(); + for(int i = 0; i < dataArray.size(); i++) + { + QJsonValue value = dataArray.at(i); + float t = value.toVariant().toFloat(); + vec.push_back(t); +// global::m_featureData.push_back(t); + } + groupdata.mapNametoData[dataType] = vec; + } + + } + qDebug()<<"::Dealdat::SetChannelSetting() groupdata.mapNametoData.size()"< &DataParsing::getFeatureData() +{ + if(m_groupdata.size() == 0) + { + qDebug() << "解析失败"; + } + else + { + qDebug() << "解析成功"; + } + return m_groupdata; +} diff --git a/ChaosDataPlayer/DataParsing.h b/ChaosDataPlayer/DataParsing.h new file mode 100644 index 0000000..4a8d462 --- /dev/null +++ b/ChaosDataPlayer/DataParsing.h @@ -0,0 +1,42 @@ +#ifndef DATAPARSING_H +#define DATAPARSING_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//通道组数据格式 +typedef struct +{ + QString Channelid; + QString ChannelType; + QMap> mapNametoData; +}GroupData; + +class DataParsing : public QObject +{ + Q_OBJECT +public: + explicit DataParsing(QObject *parent = nullptr); + ~DataParsing(); + + + void SetChannelSetting(const QString& str); + QVector & getFeatureData(); + + +signals: + +private: + QJsonObject mJsonChannelSetting; + QVector m_groupdata; //通道组数据 +}; + +#endif // DATAPARSING_H diff --git a/ChaosDataPlayer/FilterForm.cpp b/ChaosDataPlayer/FilterForm.cpp new file mode 100644 index 0000000..bc29344 --- /dev/null +++ b/ChaosDataPlayer/FilterForm.cpp @@ -0,0 +1,56 @@ +#include "FilterForm.h" +#include "ui_FilterForm.h" +#include "QMessageBox" +#include +#include "msgbox.h" + +FilterForm::FilterForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::FilterForm) +{ + ui->setupUi(this); + resize(500,320); + setWindowTitle("滤波"); + connect(ui->Btn_OK, SIGNAL(clicked()), this, SLOT(SetFilter())); + connect(ui->Btn_Cancel, SIGNAL(clicked()), this, SLOT(Cancel())); + QRegExp rx("[0-9\.]+$"); + QRegExpValidator *validator = new QRegExpValidator(rx, this); + ui->lineEdit->setValidator(validator); + ui->lineEdit_2->setValidator(validator); +} + +FilterForm::~FilterForm() +{ + delete ui; +} +void FilterForm::Cancel() +{ + this->close(); +} +void FilterForm::SetFilter() +{ + QString Xstart = ui->lineEdit->text(); + QString Xend = ui->lineEdit_2->text(); + + if((Xstart.length() == 0 && Xend.length() == 0)) + { + MyMsgBox(QMessageBox::Warning,"警告","请输入正确信息!"); + return; + } + if(Xstart.toInt() > Xend.toInt()) + { + MyMsgBox(QMessageBox::Warning,"警告","请输入正确信息!"); + return; + } + emit sgSetFilter(Xstart+","+Xend); + this->close(); +} +void FilterForm::keyPressEvent(QKeyEvent *event) +{ + //Enter事件好像这两个都要写,只写event->key() == Qt::Key_Enter,无法实现 + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + SetFilter(); + } +} + diff --git a/ChaosDataPlayer/FilterForm.h b/ChaosDataPlayer/FilterForm.h new file mode 100644 index 0000000..9c543e6 --- /dev/null +++ b/ChaosDataPlayer/FilterForm.h @@ -0,0 +1,31 @@ +#ifndef FILTERFORM_H +#define FILTERFORM_H + +#include +#include "BaseWgt.h" +#include + +namespace Ui { +class FilterForm; +} + +class FilterForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit FilterForm(QWidget *parent = nullptr); + ~FilterForm(); + +private: + Ui::FilterForm *ui; +private slots: + void SetFilter(); + void Cancel(); +protected: + virtual void keyPressEvent(QKeyEvent *event); +signals: + void sgSetFilter(QString); +}; + +#endif // FILTERFORM_H diff --git a/ChaosDataPlayer/FilterForm.ui b/ChaosDataPlayer/FilterForm.ui new file mode 100644 index 0000000..af76186 --- /dev/null +++ b/ChaosDataPlayer/FilterForm.ui @@ -0,0 +1,167 @@ + + + FilterForm + + + + 0 + 0 + 494 + 304 + + + + Form + + + + + -10 + 220 + 494 + 76 + + + + + 0 + 30 + + + + + + 270 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 确认 + + + + + + 370 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 取消 + + + + + + + -10 + 14 + 494 + 200 + + + + + 0 + 200 + + + + + + 160 + 90 + 71 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 113 + 90 + 31 + 31 + + + + 滤波 + + + + + + 300 + 90 + 71 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 250 + 100 + 54 + 12 + + + + ----- + + + + + + 180 + 60 + 54 + 21 + + + + 起始 + + + + + + 310 + 60 + 54 + 21 + + + + 结束 + + + + + + + diff --git a/ChaosDataPlayer/GL/freeglut.h b/ChaosDataPlayer/GL/freeglut.h new file mode 100644 index 0000000..0e6f8c6 --- /dev/null +++ b/ChaosDataPlayer/GL/freeglut.h @@ -0,0 +1,22 @@ +#ifndef __FREEGLUT_H__ +#define __FREEGLUT_H__ + +/* + * freeglut.h + * + * The freeglut library include file + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "freeglut_std.h" +#include "freeglut_ext.h" + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_H__ */ diff --git a/ChaosDataPlayer/GL/freeglut_ext.h b/ChaosDataPlayer/GL/freeglut_ext.h new file mode 100644 index 0000000..0c22c4f --- /dev/null +++ b/ChaosDataPlayer/GL/freeglut_ext.h @@ -0,0 +1,271 @@ +#ifndef __FREEGLUT_EXT_H__ +#define __FREEGLUT_EXT_H__ + +/* + * freeglut_ext.h + * + * The non-GLUT-compatible extensions to the freeglut library include file + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Additional GLUT Key definitions for the Special key function + */ +#define GLUT_KEY_NUM_LOCK 0x006D +#define GLUT_KEY_BEGIN 0x006E +#define GLUT_KEY_DELETE 0x006F +#define GLUT_KEY_SHIFT_L 0x0070 +#define GLUT_KEY_SHIFT_R 0x0071 +#define GLUT_KEY_CTRL_L 0x0072 +#define GLUT_KEY_CTRL_R 0x0073 +#define GLUT_KEY_ALT_L 0x0074 +#define GLUT_KEY_ALT_R 0x0075 + +/* + * GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window + */ +#define GLUT_ACTION_EXIT 0 +#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1 +#define GLUT_ACTION_CONTINUE_EXECUTION 2 + +/* + * Create a new rendering context when the user opens a new window? + */ +#define GLUT_CREATE_NEW_CONTEXT 0 +#define GLUT_USE_CURRENT_CONTEXT 1 + +/* + * Direct/Indirect rendering context options (has meaning only in Unix/X11) + */ +#define GLUT_FORCE_INDIRECT_CONTEXT 0 +#define GLUT_ALLOW_DIRECT_CONTEXT 1 +#define GLUT_TRY_DIRECT_CONTEXT 2 +#define GLUT_FORCE_DIRECT_CONTEXT 3 + +/* + * GLUT API Extension macro definitions -- the glutGet parameters + */ +#define GLUT_INIT_STATE 0x007C + +#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9 + +#define GLUT_WINDOW_BORDER_WIDTH 0x01FA +#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB +#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */ + +#define GLUT_VERSION 0x01FC + +#define GLUT_RENDERING_CONTEXT 0x01FD +#define GLUT_DIRECT_RENDERING 0x01FE + +#define GLUT_FULL_SCREEN 0x01FF + +#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204 + +#define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205 + +#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */ + +/* + * New tokens for glutInitDisplayMode. + * Only one GLUT_AUXn bit may be used at a time. + * Value 0x0400 is defined in OpenGLUT. + */ +#define GLUT_AUX 0x1000 + +#define GLUT_AUX1 0x1000 +#define GLUT_AUX2 0x2000 +#define GLUT_AUX3 0x4000 +#define GLUT_AUX4 0x8000 + +/* + * Context-related flags, see fg_state.c + * Set the requested OpenGL version + */ +#define GLUT_INIT_MAJOR_VERSION 0x0200 +#define GLUT_INIT_MINOR_VERSION 0x0201 +#define GLUT_INIT_FLAGS 0x0202 +#define GLUT_INIT_PROFILE 0x0203 + +/* + * Flags for glutInitContextFlags, see fg_init.c + */ +#define GLUT_DEBUG 0x0001 +#define GLUT_FORWARD_COMPATIBLE 0x0002 + + +/* + * Flags for glutInitContextProfile, see fg_init.c + */ +#define GLUT_CORE_PROFILE 0x0001 +#define GLUT_COMPATIBILITY_PROFILE 0x0002 + +/* + * Process loop function, see fg_main.c + */ +FGAPI void FGAPIENTRY glutMainLoopEvent( void ); +FGAPI void FGAPIENTRY glutLeaveMainLoop( void ); +FGAPI void FGAPIENTRY glutExit ( void ); + +/* + * Window management functions, see fg_window.c + */ +FGAPI void FGAPIENTRY glutFullScreenToggle( void ); +FGAPI void FGAPIENTRY glutLeaveFullScreen( void ); + +/* + * Menu functions + */ +FGAPI void FGAPIENTRY glutSetMenuFont( int menuID, void* font ); + +/* + * Window-specific callback functions, see fg_callbacks.c + */ +FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) ); +FGAPI void FGAPIENTRY glutPositionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) ); +/* And also a destruction callback for menus */ +FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ); + +/* + * State setting and retrieval functions, see fg_state.c + */ +FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value ); +FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size); +/* A.Donev: User-data manipulation */ +FGAPI void* FGAPIENTRY glutGetWindowData( void ); +FGAPI void FGAPIENTRY glutSetWindowData(void* data); +FGAPI void* FGAPIENTRY glutGetMenuData( void ); +FGAPI void FGAPIENTRY glutSetMenuData(void* data); + +/* + * Font stuff, see fg_font.c + */ +FGAPI int FGAPIENTRY glutBitmapHeight( void* font ); +FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font ); +FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string ); +FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string ); + +/* + * Geometry functions, see fg_geometry.c + */ +FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void ); +FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void ); +FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, double offset[3], double scale ); +FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, double offset[3], double scale ); +FGAPI void FGAPIENTRY glutWireCylinder( double radius, double height, GLint slices, GLint stacks); +FGAPI void FGAPIENTRY glutSolidCylinder( double radius, double height, GLint slices, GLint stacks); + +/* + * Rest of functions for rendering Newell's teaset, found in fg_teapot.c + * NB: front facing polygons have clockwise winding, not counter clockwise + */ +FGAPI void FGAPIENTRY glutWireTeacup( double size ); +FGAPI void FGAPIENTRY glutSolidTeacup( double size ); +FGAPI void FGAPIENTRY glutWireTeaspoon( double size ); +FGAPI void FGAPIENTRY glutSolidTeaspoon( double size ); + +/* + * Extension functions, see fg_ext.c + */ +typedef void (*GLUTproc)(); +FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName ); + +/* + * Multi-touch/multi-pointer extensions + */ + +#define GLUT_HAS_MULTI 1 + +/* TODO: add device_id parameter, + cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */ +FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) ); +FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) ); + +/* + * Joystick functions, see fg_joystick.c + */ +/* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */ +/* If you have a serious need for these functions in your application, please either + * contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net, + * switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's + * "js" library. + */ +int glutJoystickGetNumAxes( int ident ); +int glutJoystickGetNumButtons( int ident ); +int glutJoystickNotWorking( int ident ); +float glutJoystickGetDeadBand( int ident, int axis ); +void glutJoystickSetDeadBand( int ident, int axis, float db ); +float glutJoystickGetSaturation( int ident, int axis ); +void glutJoystickSetSaturation( int ident, int axis, float st ); +void glutJoystickSetMinRange( int ident, float *axes ); +void glutJoystickSetMaxRange( int ident, float *axes ); +void glutJoystickSetCenter( int ident, float *axes ); +void glutJoystickGetMinRange( int ident, float *axes ); +void glutJoystickGetMaxRange( int ident, float *axes ); +void glutJoystickGetCenter( int ident, float *axes ); + +/* + * Initialization functions, see fg_init.c + */ +/* to get the typedef for va_list */ +#include +FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion ); +FGAPI void FGAPIENTRY glutInitContextFlags( int flags ); +FGAPI void FGAPIENTRY glutInitContextProfile( int profile ); +FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, va_list ap ) ); +FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) ); + +/* OpenGL >= 2.0 support */ +FGAPI void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib); +FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib); +FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2(GLint attrib); + +/* Mobile platforms lifecycle */ +FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)()); +FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int)); +/* state flags that can be passed to callback set by glutAppStatusFunc */ +#define GLUT_APPSTATUS_PAUSE 0x0001 +#define GLUT_APPSTATUS_RESUME 0x0002 + +/* + * GLUT API macro definitions -- the display mode definitions + */ +#define GLUT_CAPTIONLESS 0x0400 +#define GLUT_BORDERLESS 0x0800 +#define GLUT_SRGB 0x1000 + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_EXT_H__ */ diff --git a/ChaosDataPlayer/GL/freeglut_std.h b/ChaosDataPlayer/GL/freeglut_std.h new file mode 100644 index 0000000..55539e5 --- /dev/null +++ b/ChaosDataPlayer/GL/freeglut_std.h @@ -0,0 +1,638 @@ +#ifndef __FREEGLUT_STD_H__ +#define __FREEGLUT_STD_H__ + +/* + * freeglut_std.h + * + * The GLUT-compatible part of the freeglut library include file + * + * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. + * Written by Pawel W. Olszta, + * Creation date: Thu Dec 2 1999 + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +/* + * Under windows, we have to differentiate between static and dynamic libraries + */ +#ifdef _WIN32 +/* #pragma may not be supported by some compilers. + * Discussion by FreeGLUT developers suggests that + * Visual C++ specific code involving pragmas may + * need to move to a separate header. 24th Dec 2003 + */ + +/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library + * pragmas or to 0 to exclude library pragmas. + * The default behavior depends on the compiler/platform. + */ +# ifndef FREEGLUT_LIB_PRAGMAS +# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE) +# define FREEGLUT_LIB_PRAGMAS 1 +# else +# define FREEGLUT_LIB_PRAGMAS 0 +# endif +# endif + +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include + +/* Windows static library */ +# ifdef FREEGLUT_STATIC + +#error Static linking is not supported with this build. Please remove the FREEGLUT_STATIC preprocessor directive, or download the source code from http://freeglut.sf.net/ and build against that. + +/* Windows shared library (DLL) */ +# else + +# define FGAPIENTRY __stdcall +# if defined(FREEGLUT_EXPORTS) +# define FGAPI __declspec(dllexport) +# else +# define FGAPI __declspec(dllimport) + + /* Link with Win32 shared freeglut lib */ +# if FREEGLUT_LIB_PRAGMAS +# pragma comment (lib, "freeglut.lib") +# endif + +# endif + +# endif + +/* Drag in other Windows libraries as required by FreeGLUT */ +# if FREEGLUT_LIB_PRAGMAS +# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */ +# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */ +# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */ +# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */ +# pragma comment (lib, "user32.lib") /* link Windows user lib */ +# endif + +#else + +/* Non-Windows definition of FGAPI and FGAPIENTRY */ +# define FGAPI +# define FGAPIENTRY + +#endif + +/* + * The freeglut and GLUT API versions + */ +#define FREEGLUT 1 +#define GLUT_API_VERSION 4 +#define GLUT_XLIB_IMPLEMENTATION 13 +/* Deprecated: + cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */ +#define FREEGLUT_VERSION_2_0 1 + +/* + * Always include OpenGL and GLU headers + */ +/* Note: FREEGLUT_GLES is only used to cleanly bootstrap headers + inclusion here; use GLES constants directly + (e.g. GL_ES_VERSION_2_0) for all other needs */ +#ifdef FREEGLUT_GLES +# include +# include +# include +#elif __APPLE__ +# include +# include +#else +# include +# include +#endif + +/* + * GLUT API macro definitions -- the special key codes: + */ +#define GLUT_KEY_F1 0x0001 +#define GLUT_KEY_F2 0x0002 +#define GLUT_KEY_F3 0x0003 +#define GLUT_KEY_F4 0x0004 +#define GLUT_KEY_F5 0x0005 +#define GLUT_KEY_F6 0x0006 +#define GLUT_KEY_F7 0x0007 +#define GLUT_KEY_F8 0x0008 +#define GLUT_KEY_F9 0x0009 +#define GLUT_KEY_F10 0x000A +#define GLUT_KEY_F11 0x000B +#define GLUT_KEY_F12 0x000C +#define GLUT_KEY_LEFT 0x0064 +#define GLUT_KEY_UP 0x0065 +#define GLUT_KEY_RIGHT 0x0066 +#define GLUT_KEY_DOWN 0x0067 +#define GLUT_KEY_PAGE_UP 0x0068 +#define GLUT_KEY_PAGE_DOWN 0x0069 +#define GLUT_KEY_HOME 0x006A +#define GLUT_KEY_END 0x006B +#define GLUT_KEY_INSERT 0x006C + +/* + * GLUT API macro definitions -- mouse state definitions + */ +#define GLUT_LEFT_BUTTON 0x0000 +#define GLUT_MIDDLE_BUTTON 0x0001 +#define GLUT_RIGHT_BUTTON 0x0002 +#define GLUT_DOWN 0x0000 +#define GLUT_UP 0x0001 +#define GLUT_LEFT 0x0000 +#define GLUT_ENTERED 0x0001 + +/* + * GLUT API macro definitions -- the display mode definitions + */ +#define GLUT_RGB 0x0000 +#define GLUT_RGBA 0x0000 +#define GLUT_INDEX 0x0001 +#define GLUT_SINGLE 0x0000 +#define GLUT_DOUBLE 0x0002 +#define GLUT_ACCUM 0x0004 +#define GLUT_ALPHA 0x0008 +#define GLUT_DEPTH 0x0010 +#define GLUT_STENCIL 0x0020 +#define GLUT_MULTISAMPLE 0x0080 +#define GLUT_STEREO 0x0100 +#define GLUT_LUMINANCE 0x0200 + +/* + * GLUT API macro definitions -- windows and menu related definitions + */ +#define GLUT_MENU_NOT_IN_USE 0x0000 +#define GLUT_MENU_IN_USE 0x0001 +#define GLUT_NOT_VISIBLE 0x0000 +#define GLUT_VISIBLE 0x0001 +#define GLUT_HIDDEN 0x0000 +#define GLUT_FULLY_RETAINED 0x0001 +#define GLUT_PARTIALLY_RETAINED 0x0002 +#define GLUT_FULLY_COVERED 0x0003 + +/* + * GLUT API macro definitions -- fonts definitions + * + * Steve Baker suggested to make it binary compatible with GLUT: + */ +#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__) +# define GLUT_STROKE_ROMAN ((void *)0x0000) +# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001) +# define GLUT_BITMAP_9_BY_15 ((void *)0x0002) +# define GLUT_BITMAP_8_BY_13 ((void *)0x0003) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005) +# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006) +# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007) +# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008) +#else + /* + * I don't really know if it's a good idea... But here it goes: + */ + extern void* glutStrokeRoman; + extern void* glutStrokeMonoRoman; + extern void* glutBitmap9By15; + extern void* glutBitmap8By13; + extern void* glutBitmapTimesRoman10; + extern void* glutBitmapTimesRoman24; + extern void* glutBitmapHelvetica10; + extern void* glutBitmapHelvetica12; + extern void* glutBitmapHelvetica18; + + /* + * Those pointers will be used by following definitions: + */ +# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman) +# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman) +# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15) +# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13) +# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10) +# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24) +# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10) +# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12) +# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18) +#endif + +/* + * GLUT API macro definitions -- the glutGet parameters + */ +#define GLUT_WINDOW_X 0x0064 +#define GLUT_WINDOW_Y 0x0065 +#define GLUT_WINDOW_WIDTH 0x0066 +#define GLUT_WINDOW_HEIGHT 0x0067 +#define GLUT_WINDOW_BUFFER_SIZE 0x0068 +#define GLUT_WINDOW_STENCIL_SIZE 0x0069 +#define GLUT_WINDOW_DEPTH_SIZE 0x006A +#define GLUT_WINDOW_RED_SIZE 0x006B +#define GLUT_WINDOW_GREEN_SIZE 0x006C +#define GLUT_WINDOW_BLUE_SIZE 0x006D +#define GLUT_WINDOW_ALPHA_SIZE 0x006E +#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072 +#define GLUT_WINDOW_DOUBLEBUFFER 0x0073 +#define GLUT_WINDOW_RGBA 0x0074 +#define GLUT_WINDOW_PARENT 0x0075 +#define GLUT_WINDOW_NUM_CHILDREN 0x0076 +#define GLUT_WINDOW_COLORMAP_SIZE 0x0077 +#define GLUT_WINDOW_NUM_SAMPLES 0x0078 +#define GLUT_WINDOW_STEREO 0x0079 +#define GLUT_WINDOW_CURSOR 0x007A + +#define GLUT_SCREEN_WIDTH 0x00C8 +#define GLUT_SCREEN_HEIGHT 0x00C9 +#define GLUT_SCREEN_WIDTH_MM 0x00CA +#define GLUT_SCREEN_HEIGHT_MM 0x00CB +#define GLUT_MENU_NUM_ITEMS 0x012C +#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190 +#define GLUT_INIT_WINDOW_X 0x01F4 +#define GLUT_INIT_WINDOW_Y 0x01F5 +#define GLUT_INIT_WINDOW_WIDTH 0x01F6 +#define GLUT_INIT_WINDOW_HEIGHT 0x01F7 +#define GLUT_INIT_DISPLAY_MODE 0x01F8 +#define GLUT_ELAPSED_TIME 0x02BC +#define GLUT_WINDOW_FORMAT_ID 0x007B + +/* + * GLUT API macro definitions -- the glutDeviceGet parameters + */ +#define GLUT_HAS_KEYBOARD 0x0258 +#define GLUT_HAS_MOUSE 0x0259 +#define GLUT_HAS_SPACEBALL 0x025A +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B +#define GLUT_HAS_TABLET 0x025C +#define GLUT_NUM_MOUSE_BUTTONS 0x025D +#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E +#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F +#define GLUT_NUM_DIALS 0x0260 +#define GLUT_NUM_TABLET_BUTTONS 0x0261 +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262 +#define GLUT_DEVICE_KEY_REPEAT 0x0263 +#define GLUT_HAS_JOYSTICK 0x0264 +#define GLUT_OWNS_JOYSTICK 0x0265 +#define GLUT_JOYSTICK_BUTTONS 0x0266 +#define GLUT_JOYSTICK_AXES 0x0267 +#define GLUT_JOYSTICK_POLL_RATE 0x0268 + +/* + * GLUT API macro definitions -- the glutLayerGet parameters + */ +#define GLUT_OVERLAY_POSSIBLE 0x0320 +#define GLUT_LAYER_IN_USE 0x0321 +#define GLUT_HAS_OVERLAY 0x0322 +#define GLUT_TRANSPARENT_INDEX 0x0323 +#define GLUT_NORMAL_DAMAGED 0x0324 +#define GLUT_OVERLAY_DAMAGED 0x0325 + +/* + * GLUT API macro definitions -- the glutVideoResizeGet parameters + */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384 +#define GLUT_VIDEO_RESIZE_IN_USE 0x0385 +#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386 +#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389 +#define GLUT_VIDEO_RESIZE_X 0x038A +#define GLUT_VIDEO_RESIZE_Y 0x038B +#define GLUT_VIDEO_RESIZE_WIDTH 0x038C +#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D + +/* + * GLUT API macro definitions -- the glutUseLayer parameters + */ +#define GLUT_NORMAL 0x0000 +#define GLUT_OVERLAY 0x0001 + +/* + * GLUT API macro definitions -- the glutGetModifiers parameters + */ +#define GLUT_ACTIVE_SHIFT 0x0001 +#define GLUT_ACTIVE_CTRL 0x0002 +#define GLUT_ACTIVE_ALT 0x0004 + +/* + * GLUT API macro definitions -- the glutSetCursor parameters + */ +#define GLUT_CURSOR_RIGHT_ARROW 0x0000 +#define GLUT_CURSOR_LEFT_ARROW 0x0001 +#define GLUT_CURSOR_INFO 0x0002 +#define GLUT_CURSOR_DESTROY 0x0003 +#define GLUT_CURSOR_HELP 0x0004 +#define GLUT_CURSOR_CYCLE 0x0005 +#define GLUT_CURSOR_SPRAY 0x0006 +#define GLUT_CURSOR_WAIT 0x0007 +#define GLUT_CURSOR_TEXT 0x0008 +#define GLUT_CURSOR_CROSSHAIR 0x0009 +#define GLUT_CURSOR_UP_DOWN 0x000A +#define GLUT_CURSOR_LEFT_RIGHT 0x000B +#define GLUT_CURSOR_TOP_SIDE 0x000C +#define GLUT_CURSOR_BOTTOM_SIDE 0x000D +#define GLUT_CURSOR_LEFT_SIDE 0x000E +#define GLUT_CURSOR_RIGHT_SIDE 0x000F +#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013 +#define GLUT_CURSOR_INHERIT 0x0064 +#define GLUT_CURSOR_NONE 0x0065 +#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066 + +/* + * GLUT API macro definitions -- RGB color component specification definitions + */ +#define GLUT_RED 0x0000 +#define GLUT_GREEN 0x0001 +#define GLUT_BLUE 0x0002 + +/* + * GLUT API macro definitions -- additional keyboard and joystick definitions + */ +#define GLUT_KEY_REPEAT_OFF 0x0000 +#define GLUT_KEY_REPEAT_ON 0x0001 +#define GLUT_KEY_REPEAT_DEFAULT 0x0002 + +#define GLUT_JOYSTICK_BUTTON_A 0x0001 +#define GLUT_JOYSTICK_BUTTON_B 0x0002 +#define GLUT_JOYSTICK_BUTTON_C 0x0004 +#define GLUT_JOYSTICK_BUTTON_D 0x0008 + +/* + * GLUT API macro definitions -- game mode definitions + */ +#define GLUT_GAME_MODE_ACTIVE 0x0000 +#define GLUT_GAME_MODE_POSSIBLE 0x0001 +#define GLUT_GAME_MODE_WIDTH 0x0002 +#define GLUT_GAME_MODE_HEIGHT 0x0003 +#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004 +#define GLUT_GAME_MODE_REFRESH_RATE 0x0005 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006 + +/* + * Initialization functions, see fglut_init.c + */ +FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv ); +FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y ); +FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height ); +FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode ); +FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode ); + +/* + * Process loop function, see fg_main.c + */ +FGAPI void FGAPIENTRY glutMainLoop( void ); + +/* + * Window management functions, see fg_window.c + */ +FGAPI int FGAPIENTRY glutCreateWindow( const char* title ); +FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutDestroyWindow( int window ); +FGAPI void FGAPIENTRY glutSetWindow( int window ); +FGAPI int FGAPIENTRY glutGetWindow( void ); +FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title ); +FGAPI void FGAPIENTRY glutSetIconTitle( const char* title ); +FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height ); +FGAPI void FGAPIENTRY glutPositionWindow( int x, int y ); +FGAPI void FGAPIENTRY glutShowWindow( void ); +FGAPI void FGAPIENTRY glutHideWindow( void ); +FGAPI void FGAPIENTRY glutIconifyWindow( void ); +FGAPI void FGAPIENTRY glutPushWindow( void ); +FGAPI void FGAPIENTRY glutPopWindow( void ); +FGAPI void FGAPIENTRY glutFullScreen( void ); + +/* + * Display-related functions, see fg_display.c + */ +FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window ); +FGAPI void FGAPIENTRY glutPostRedisplay( void ); +FGAPI void FGAPIENTRY glutSwapBuffers( void ); + +/* + * Mouse cursor functions, see fg_cursor.c + */ +FGAPI void FGAPIENTRY glutWarpPointer( int x, int y ); +FGAPI void FGAPIENTRY glutSetCursor( int cursor ); + +/* + * Overlay stuff, see fg_overlay.c + */ +FGAPI void FGAPIENTRY glutEstablishOverlay( void ); +FGAPI void FGAPIENTRY glutRemoveOverlay( void ); +FGAPI void FGAPIENTRY glutUseLayer( GLenum layer ); +FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void ); +FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window ); +FGAPI void FGAPIENTRY glutShowOverlay( void ); +FGAPI void FGAPIENTRY glutHideOverlay( void ); + +/* + * Menu stuff, see fg_menu.c + */ +FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) ); +FGAPI void FGAPIENTRY glutDestroyMenu( int menu ); +FGAPI int FGAPIENTRY glutGetMenu( void ); +FGAPI void FGAPIENTRY glutSetMenu( int menu ); +FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value ); +FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu ); +FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value ); +FGAPI void FGAPIENTRY glutRemoveMenuItem( int item ); +FGAPI void FGAPIENTRY glutAttachMenu( int button ); +FGAPI void FGAPIENTRY glutDetachMenu( int button ); + +/* + * Global callback functions, see fg_callbacks.c + */ +FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value ); +FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ); + +/* + * Window-specific callback functions, see fg_callbacks.c + */ +FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ); +FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ); +FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ); +FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ); +FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ); +FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ); + +FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ); +FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ); +FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ); + +/* + * State setting and retrieval functions, see fg_state.c + */ +FGAPI int FGAPIENTRY glutGet( GLenum query ); +FGAPI int FGAPIENTRY glutDeviceGet( GLenum query ); +FGAPI int FGAPIENTRY glutGetModifiers( void ); +FGAPI int FGAPIENTRY glutLayerGet( GLenum query ); + +/* + * Font stuff, see fg_font.c + */ +FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character ); +FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character ); +FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character ); +FGAPI GLfloat FGAPIENTRY glutStrokeWidthf( void* font, int character ); /* GLUT 3.8 */ +FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string ); +FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string ); +FGAPI GLfloat FGAPIENTRY glutStrokeLengthf( void* font, const unsigned char *string ); /* GLUT 3.8 */ + +/* + * Geometry functions, see fg_geometry.c + */ + +FGAPI void FGAPIENTRY glutWireCube( double size ); +FGAPI void FGAPIENTRY glutSolidCube( double size ); +FGAPI void FGAPIENTRY glutWireSphere( double radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidSphere( double radius, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutWireCone( double base, double height, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutSolidCone( double base, double height, GLint slices, GLint stacks ); +FGAPI void FGAPIENTRY glutWireTorus( double innerRadius, double outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutSolidTorus( double innerRadius, double outerRadius, GLint sides, GLint rings ); +FGAPI void FGAPIENTRY glutWireDodecahedron( void ); +FGAPI void FGAPIENTRY glutSolidDodecahedron( void ); +FGAPI void FGAPIENTRY glutWireOctahedron( void ); +FGAPI void FGAPIENTRY glutSolidOctahedron( void ); +FGAPI void FGAPIENTRY glutWireTetrahedron( void ); +FGAPI void FGAPIENTRY glutSolidTetrahedron( void ); +FGAPI void FGAPIENTRY glutWireIcosahedron( void ); +FGAPI void FGAPIENTRY glutSolidIcosahedron( void ); + +/* + * Teapot rendering functions, found in fg_teapot.c + * NB: front facing polygons have clockwise winding, not counter clockwise + */ +FGAPI void FGAPIENTRY glutWireTeapot( double size ); +FGAPI void FGAPIENTRY glutSolidTeapot( double size ); + +/* + * Game mode functions, see fg_gamemode.c + */ +FGAPI void FGAPIENTRY glutGameModeString( const char* string ); +FGAPI int FGAPIENTRY glutEnterGameMode( void ); +FGAPI void FGAPIENTRY glutLeaveGameMode( void ); +FGAPI int FGAPIENTRY glutGameModeGet( GLenum query ); + +/* + * Video resize functions, see fg_videoresize.c + */ +FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query ); +FGAPI void FGAPIENTRY glutSetupVideoResizing( void ); +FGAPI void FGAPIENTRY glutStopVideoResizing( void ); +FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height ); +FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height ); + +/* + * Colormap functions, see fg_misc.c + */ +FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue ); +FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component ); +FGAPI void FGAPIENTRY glutCopyColormap( int window ); + +/* + * Misc keyboard and joystick functions, see fg_misc.c + */ +FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore ); +FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode ); +FGAPI void FGAPIENTRY glutForceJoystickFunc( void ); + +/* + * Misc functions, see fg_misc.c + */ +FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension ); +FGAPI void FGAPIENTRY glutReportErrors( void ); + +/* Comment from glut.h of classic GLUT: + + Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* to get the prototype for exit() */ +#include + +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__) +FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int)); +#ifndef FREEGLUT_BUILDING_LIB +#if defined(__GNUC__) +#define FGUNUSED __attribute__((unused)) +#else +#define FGUNUSED +#endif +static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif + +#ifdef __cplusplus + } +#endif + +/*** END OF FILE ***/ + +#endif /* __FREEGLUT_STD_H__ */ diff --git a/ChaosDataPlayer/GL/glut.h b/ChaosDataPlayer/GL/glut.h new file mode 100644 index 0000000..6191f77 --- /dev/null +++ b/ChaosDataPlayer/GL/glut.h @@ -0,0 +1,21 @@ +#ifndef __GLUT_H__ +#define __GLUT_H__ + +/* + * glut.h + * + * The freeglut library include file + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "freeglut_std.h" + +/*** END OF FILE ***/ + +#endif /* __GLUT_H__ */ diff --git a/ChaosDataPlayer/GSL/bin/bashdb b/ChaosDataPlayer/GSL/bin/bashdb new file mode 100644 index 0000000..e95c8c5 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/bashdb @@ -0,0 +1,159 @@ +#!/bin/bash +# -*- shell-script -*- +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, +# 2009 Rocky Bernstein rocky@gnu.org +# +# bashdb is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. +# +# bashdb is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with bashdb; see the file COPYING. If not, write to the Free Software +# Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. +# + +# The alternate way to invoke debugger, "bash --debugger", has some +# advantages: it sets $0 correctly and doesn't show this script in +# the call trace. However the bash has been a bit inflexible and +# quirky so sadly this script seems to be needed more than it would +# normally. + +[[ -z $_Dbg_ver ]] && typeset _Dbg_ver=\ +'$Id: bashdb.in,v 1.48 2008/10/30 08:22:23 rockyb Exp $' + +# This routine gets called via the -c or --command option and its sole +# purpose is to capture the command string such as via "x $*" or +# in a traceback ("where"). +function _Dbg_eval { + eval $* +} + +# Name we refer to ourselves by +typeset _Dbg_debugger_name='bashdb' + +# The shell we are configured to run under. +typeset _Dbg_shell='/bin/bash' + +# The release name we are configured to run under. +typeset _Dbg_release='4.0-0.4' + +# The short shell name. Helps keep code common in bash, zsh, and ksh debuggers. +typeset _Dbg_shell_name=${_Dbg_shell##*/} # Equivalent to basename(_Dbg_shell) + +# Original $0. Note we can't set this in an include. +typeset _Dbg_orig_0=$0 + +# Equivalent to basename $0; the short program name +typeset _Dbg_pname=${0##*/} + +## Stuff set by autoconf/configure ### +typeset prefix=/usr/local +typeset _Dbg_libdir=${prefix}/share/bashdb +### + +[[ ! -d $_Dbg_libdir ]] && _Dbg_libdir='.' +# Parse just the libdir option +# Show basename only in location listing. This is needed in regression tests +typeset -i _Dbg_basename_only=${BASHDB_BASENAME_ONLY:-0} + +typeset _Dbg_bashdb_main=/usr/local/lib/bashdb/bashdb-main.inc +typeset -x _Dbg_libdir=${_Dbg_bashdb_main%/*} # dirname(_Dbg_bashdb_main) +# typeset _Dbg_libdir=${prefix}/share/bashdb + +typeset _Dbg_main=dbg-main.sh +typeset _Dbg_bindir=$(dirname $0) + +# What to set for location of helper routines? +if [[ ! -e $_Dbg_libdir/$_Dbg_main ]] ; then + # Use bindir/../share as fallback + _Dbg_libdir= + if [[ -d $_Dbg_bindir/../share/bashdb ]] ; then + _Dbg_libdir=$_Dbg_bindir/../share/bashdb + fi +fi + +# Parse just the library option +typeset -ax _Dbg_script_args=("$@") +typeset -i _Dbg_i +for ((_Dbg_i=0; _Dbg_i<${#_Dbg_script_args[@]}-1; _Dbg_i++)) ; do + typeset arg=${_Dbg_script_args[$_Dbg_i]} + if [[ $arg == '-L' || $arg == '--library' ]] ; then + ((_Dbg_i++)) + _Dbg_libdir="${_Dbg_script_args[$_Dbg_i]}" + break + fi +done +if [[ ! -d $_Dbg_libdir ]] && [[ ! -d $_Dbg_libdir ]] ; then + echo "${_Dbg_pname}: Can't read debugger library directory '${_Dbg_libdir}'." + echo "${_Dbg_pname}: Perhaps bashdb is installed wrong (if its installed)." >&2 + echo "${_Dbg_pname}: Try running bashdb using -L (with a different directory)." >&2 + echo "${_Dbg_pname}: Run bashdb --help for a list and explanation of options." >&2 + exit 1 +fi + +# Pull in the rest of the debugger code. +typeset _Dbg_main="$_Dbg_libdir/dbg-main.sh" +if [[ ! -r $_Dbg_main ]] ; then + print "${_Dbg_pname}: Can't read debugger library file '${_Dbg_main}'." + print "${_Dbg_pname}: Perhaps bashdb is installed wrong (if its installed)." >&2 + print "${_Dbg_pname}: Try running bashdb using -L (with a different directory)." >&2 + print "${_Dbg_pname}: Run bashdb --help for a list and explanation of options." >&2 + exit 1 + +fi + +. $_Dbg_libdir/dbg-main.sh ; + +# I don't know why when this is done in dbg-opts.sh it doesn't have +# an effect. +((OPTLIND > 0)) && shift "$((OPTLIND - 1))" + +if (($# == 0)) && [[ -z $_Dbg_EXECUTION_STRING ]] ; then + echo >&2 "${_Dbg_pname}: need to give a script to debug or use the -c option." + exit 1 +fi + +_Dbg_script_file="$1" +shift + +if [[ ! -d $_Dbg_tmpdir ]] && [[ ! -w $_Dbg_tmpdir ]] ; then + echo "${_Dbg_pname}: cannot write to temp directory $_Dbg_tmpdir." >&2 + echo "${_Dbg_pname}: Use -T try directory location." >&2 + exit 1 +fi + +# Note that this is called via bashdb rather than "bash --debugger" +_Dbg_script=1 + +if [[ -n $_Dbg_EXECUTION_STRING ]] ; then + _Dbg_script_file=$(_Dbg_tempname cmd) + echo "$_Dbg_EXECUTION_STRING" >$_Dbg_script_file +fi + +if [[ ! -r "$_Dbg_script_file" ]] ; then + echo "${_Dbg_pname}: cannot read program to debug: ${_Dbg_script_file}." >&2 + exit 1 +fi + +typeset -r _Dbg_Dbg_script_file=$(_Dbg_expand_filename $_Dbg_script_file) + +if ((_Dbg_linetrace)) ; then + # No stepping. + _Dbg_write_journal_eval "_Dbg_step_ignore=-1" + _Dbg_QUIT_ON_QUIT=1 +else + # Set to skip over statements up to ". $_Dbg_script_file" + _Dbg_write_journal_eval "_Dbg_step_ignore=3" +fi +_Dbg_init_default_traps +trap '_Dbg_debug_trap_handler 0 "$BASH_COMMAND" "$@"' DEBUG +set -o functrace +. "$_Dbg_script_file" + +# end of bashdb diff --git a/ChaosDataPlayer/GSL/bin/git-flow b/ChaosDataPlayer/GSL/bin/git-flow new file mode 100644 index 0000000..b830d1b --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow @@ -0,0 +1,123 @@ +#!/bin/sh +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +# set this to workaround expr problems in shFlags on freebsd +if uname -s | egrep -iq 'bsd'; then export EXPR_COMPAT=1; fi + +# enable debug mode +if [ "$DEBUG" = "yes" ]; then + set -x +fi + +# The sed expression here replaces all backslashes by forward slashes. +# This helps our Windows users, while not bothering our Unix users. +export GITFLOW_DIR=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +usage() { + echo "usage: git flow " + echo + echo "Available subcommands are:" + echo " init Initialize a new git repo with support for the branching model." + echo " feature Manage your feature branches." + echo " release Manage your release branches." + echo " hotfix Manage your hotfix branches." + echo " support Manage your support branches." + echo " version Shows version information." + echo + echo "Try 'git flow help' for details." +} + +main() { + if [ $# -lt 1 ]; then + usage + exit 1 + fi + + # load common functionality + . "$GITFLOW_DIR/gitflow-common" + + # This environmental variable fixes non-POSIX getopt style argument + # parsing, effectively breaking git-flow subcommand parsing on several + # Linux platforms. + export POSIXLY_CORRECT=1 + + # use the shFlags project to parse the command line arguments + . "$GITFLOW_DIR/shflags" + FLAGS_PARENT="git flow" + + # allow user to request git action logging + DEFINE_boolean show_commands false 'show actions taken (git commands)' g + + # do actual parsing + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # sanity checks + SUBCOMMAND="$1"; shift + + if [ ! -e "$GITFLOW_DIR/git-flow-$SUBCOMMAND" ]; then + usage + exit 1 + fi + + # run command + . "$GITFLOW_DIR/git-flow-$SUBCOMMAND" + FLAGS_PARENT="git flow $SUBCOMMAND" + + # test if the first argument is a flag (i.e. starts with '-') + # in that case, we interpret this arg as a flag for the default + # command + SUBACTION="default" + if [ "$1" != "" ] && { ! echo "$1" | grep -q "^-"; } then + SUBACTION="$1"; shift + fi + if ! type "cmd_$SUBACTION" >/dev/null 2>&1; then + warn "Unknown subcommand: '$SUBACTION'" + usage + exit 1 + fi + + # run the specified action + if [ $SUBACTION != "help" ] && [ $SUBCOMMAND != "init" ] ; then + init + fi + cmd_$SUBACTION "$@" +} + +main "$@" diff --git a/ChaosDataPlayer/GSL/bin/git-flow-feature b/ChaosDataPlayer/GSL/bin/git-flow-feature new file mode 100644 index 0000000..55198ad --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-feature @@ -0,0 +1,530 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +init() { + require_git_repo + require_gitflow_initialized + gitflow_load_settings + PREFIX=$(git config --get gitflow.prefix.feature) +} + +usage() { + echo "usage: git flow feature [list] [-v]" + echo " git flow feature start [-F] []" + echo " git flow feature finish [-rFkDS] []" + echo " git flow feature publish " + echo " git flow feature track " + echo " git flow feature diff []" + echo " git flow feature rebase [-i] []" + echo " git flow feature checkout []" + echo " git flow feature pull [-r] []" +} + +cmd_default() { + cmd_list "$@" +} + +cmd_list() { + DEFINE_boolean verbose false 'verbose (more) output' v + parse_args "$@" + + local feature_branches + local current_branch + local short_names + feature_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + if [ -z "$feature_branches" ]; then + warn "No feature branches exist." + warn "" + warn "You can start a new feature branch:" + warn "" + warn " git flow feature start []" + warn "" + exit 0 + fi + current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g') + short_names=$(echo "$feature_branches" | sed "s ^$PREFIX g") + + # determine column width first + local width=0 + local branch + for branch in $short_names; do + local len=${#branch} + width=$(max $width $len) + done + width=$(($width+3)) + + local branch + for branch in $short_names; do + local fullname=$PREFIX$branch + local base=$(git merge-base "$fullname" "$DEVELOP_BRANCH") + local develop_sha=$(git rev-parse "$DEVELOP_BRANCH") + local branch_sha=$(git rev-parse "$fullname") + if [ "$fullname" = "$current_branch" ]; then + printf "* " + else + printf " " + fi + if flag verbose; then + printf "%-${width}s" "$branch" + if [ "$branch_sha" = "$develop_sha" ]; then + printf "(no commits yet)" + elif [ "$base" = "$branch_sha" ]; then + printf "(is behind develop, may ff)" + elif [ "$base" = "$develop_sha" ]; then + printf "(based on latest develop)" + else + printf "(may be rebased)" + fi + else + printf "%s" "$branch" + fi + echo + done +} + +cmd_help() { + usage + exit 0 +} + +require_name_arg() { + if [ "$NAME" = "" ]; then + warn "Missing argument " + usage + exit 1 + fi +} + +expand_nameprefix_arg() { + require_name_arg + + local expanded_name + local exitcode + expanded_name=$(gitflow_resolve_nameprefix "$NAME" "$PREFIX") + exitcode=$? + case $exitcode in + 0) NAME=$expanded_name + BRANCH=$PREFIX$NAME + ;; + *) exit 1 ;; + esac +} + +use_current_feature_branch_name() { + local current_branch=$(git_current_branch) + if startswith "$current_branch" "$PREFIX"; then + BRANCH=$current_branch + NAME=${BRANCH#$PREFIX} + else + warn "The current HEAD is no feature branch." + warn "Please specify a argument." + exit 1 + fi +} + +expand_nameprefix_arg_or_current() { + if [ "$NAME" != "" ]; then + expand_nameprefix_arg + require_branch "$PREFIX$NAME" + else + use_current_feature_branch_name + fi +} + +name_or_current() { + if [ -z "$NAME" ]; then + use_current_feature_branch_name + fi +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables + NAME=$1 + BRANCH=$PREFIX$NAME +} + +parse_remote_name() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables + REMOTE=$1 + NAME=$2 + BRANCH=$PREFIX$NAME +} + +cmd_start() { + DEFINE_boolean fetch false 'fetch from origin before performing local operation' F + parse_args "$@" + BASE=${2:-$DEVELOP_BRANCH} + require_name_arg + + # sanity checks + require_branch_absent "$BRANCH" + + # update the local repo with remote changes, if asked + if flag fetch; then + git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" + fi + + # if the origin branch counterpart exists, assert that the local branch + # isn't behind it (to avoid unnecessary rebasing) + if git_branch_exists "$ORIGIN/$DEVELOP_BRANCH"; then + require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" + fi + + # create branch + if ! git_do checkout -b "$BRANCH" "$BASE"; then + die "Could not create feature branch '$BRANCH'" + fi + + echo + echo "Summary of actions:" + echo "- A new branch '$BRANCH' was created, based on '$BASE'" + echo "- You are now on branch '$BRANCH'" + echo "" + echo "Now, start committing on your feature. When done, use:" + echo "" + echo " git flow feature finish $NAME" + echo +} + +cmd_finish() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + DEFINE_boolean rebase false "rebase instead of merge" r + DEFINE_boolean keep false "keep branch after performing finish" k + DEFINE_boolean force_delete false "force delete feature branch after finish" D + DEFINE_boolean squash false "squash feature during merge" S + parse_args "$@" + expand_nameprefix_arg_or_current + + # sanity checks + require_branch "$BRANCH" + + # detect if we're restoring from a merge conflict + if [ -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" ]; then + # + # TODO: detect that we're working on the correct branch here! + # The user need not necessarily have given the same $NAME twice here + # (although he/she should). + # + + # TODO: git_is_clean_working_tree() should provide an alternative + # exit code for "unmerged changes in working tree", which we should + # actually be testing for here + if git_is_clean_working_tree; then + FINISH_BASE=$(cat "$DOT_GIT_DIR/.gitflow/MERGE_BASE") + + # Since the working tree is now clean, either the user did a + # succesfull merge manually, or the merge was cancelled. + # We detect this using git_is_branch_merged_into() + if git_is_branch_merged_into "$BRANCH" "$FINISH_BASE"; then + rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" + helper_finish_cleanup + exit 0 + else + # If the user cancelled the merge and decided to wait until later, + # that's fine. But we have to acknowledge this by removing the + # MERGE_BASE file and continuing normal execution of the finish + rm -f "$DOT_GIT_DIR/.gitflow/MERGE_BASE" + fi + else + echo + echo "Merge conflicts not resolved yet, use:" + echo " git mergetool" + echo " git commit" + echo + echo "You can then complete the finish by running it again:" + echo " git flow feature finish $NAME" + echo + exit 1 + fi + fi + + # sanity checks + require_clean_working_tree + + # update local repo with remote changes first, if asked + if has "$ORIGIN/$BRANCH" $(git_remote_branches); then + if flag fetch; then + git_do fetch -q "$ORIGIN" "$BRANCH" + git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" + fi + fi + + if has "$ORIGIN/$BRANCH" $(git_remote_branches); then + require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH" + fi + if has "$ORIGIN/$DEVELOP_BRANCH" $(git_remote_branches); then + require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" + fi + + # if the user wants to rebase, do that first + if flag rebase; then + if ! git flow feature rebase "$NAME" "$DEVELOP_BRANCH"; then + warn "Finish was aborted due to conflicts during rebase." + warn "Please finish the rebase manually now." + warn "When finished, re-run:" + warn " git flow feature finish '$NAME' '$DEVELOP_BRANCH'" + exit 1 + fi + fi + + # merge into BASE + git_do checkout "$DEVELOP_BRANCH" + if [ "$(git rev-list -n2 "$DEVELOP_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then + git_do merge --ff "$BRANCH" + else + if noflag squash; then + git_do merge --no-ff "$BRANCH" + else + git_do merge --squash "$BRANCH" + git_do commit + git_do merge "$BRANCH" + fi + fi + + if [ $? -ne 0 ]; then + # oops.. we have a merge conflict! + # write the given $DEVELOP_BRANCH to a temporary file (we need it later) + mkdir -p "$DOT_GIT_DIR/.gitflow" + echo "$DEVELOP_BRANCH" > "$DOT_GIT_DIR/.gitflow/MERGE_BASE" + echo + echo "There were merge conflicts. To resolve the merge conflict manually, use:" + echo " git mergetool" + echo " git commit" + echo + echo "You can then complete the finish by running it again:" + echo " git flow feature finish $NAME" + echo + exit 1 + fi + + # when no merge conflict is detected, just clean up the feature branch + helper_finish_cleanup +} + +helper_finish_cleanup() { + # sanity checks + require_branch "$BRANCH" + require_clean_working_tree + + # delete branch + if flag fetch; then + git_do push "$ORIGIN" ":refs/heads/$BRANCH" + fi + + + if noflag keep; then + if flag force_delete; then + git_do branch -D "$BRANCH" + else + git_do branch -d "$BRANCH" + fi + fi + + echo + echo "Summary of actions:" + echo "- The feature branch '$BRANCH' was merged into '$DEVELOP_BRANCH'" + #echo "- Merge conflicts were resolved" # TODO: Add this line when it's supported + if flag keep; then + echo "- Feature branch '$BRANCH' is still available" + else + echo "- Feature branch '$BRANCH' has been removed" + fi + echo "- You are now on branch '$DEVELOP_BRANCH'" + echo +} + +cmd_publish() { + parse_args "$@" + expand_nameprefix_arg + + # sanity checks + require_clean_working_tree + require_branch "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch_absent "$ORIGIN/$BRANCH" + + # create remote branch + git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH" + git_do fetch -q "$ORIGIN" + + # configure remote tracking + git_do config "branch.$BRANCH.remote" "$ORIGIN" + git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH" + git_do checkout "$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote branch '$BRANCH' was created" + echo "- The local branch '$BRANCH' was configured to track the remote branch" + echo "- You are now on branch '$BRANCH'" + echo +} + +cmd_track() { + parse_args "$@" + require_name_arg + + # sanity checks + require_clean_working_tree + require_branch_absent "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch "$ORIGIN/$BRANCH" + + # create tracking branch + git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote tracking branch '$BRANCH' was created" + echo "- You are now on branch '$BRANCH'" + echo +} + +cmd_diff() { + parse_args "$@" + + if [ "$NAME" != "" ]; then + expand_nameprefix_arg + BASE=$(git merge-base "$DEVELOP_BRANCH" "$BRANCH") + git diff "$BASE..$BRANCH" + else + if ! git_current_branch | grep -q "^$PREFIX"; then + die "Not on a feature branch. Name one explicitly." + fi + + BASE=$(git merge-base "$DEVELOP_BRANCH" HEAD) + git diff "$BASE" + fi +} + +cmd_checkout() { + parse_args "$@" + + if [ "$NAME" != "" ]; then + expand_nameprefix_arg + git_do checkout "$BRANCH" + else + die "Name a feature branch explicitly." + fi +} + +cmd_co() { + # Alias for checkout + cmd_checkout "$@" +} + +cmd_rebase() { + DEFINE_boolean interactive false 'do an interactive rebase' i + parse_args "$@" + expand_nameprefix_arg_or_current + warn "Will try to rebase '$NAME'..." + require_clean_working_tree + require_branch "$BRANCH" + + git_do checkout -q "$BRANCH" + local OPTS= + if flag interactive; then + OPTS="$OPTS -i" + fi + git_do rebase $OPTS "$DEVELOP_BRANCH" +} + +avoid_accidental_cross_branch_action() { + local current_branch=$(git_current_branch) + if [ "$BRANCH" != "$current_branch" ]; then + warn "Trying to pull from '$BRANCH' while currently on branch '$current_branch'." + warn "To avoid unintended merges, git-flow aborted." + return 1 + fi + return 0 +} + +cmd_pull() { + #DEFINE_string prefix false 'alternative remote feature branch name prefix' p + DEFINE_boolean rebase false "pull with rebase" r + parse_remote_name "$@" + + if [ -z "$REMOTE" ]; then + die "Name a remote explicitly." + fi + name_or_current + + # To avoid accidentally merging different feature branches into each other, + # die if the current feature branch differs from the requested $NAME + # argument. + local current_branch=$(git_current_branch) + if startswith "$current_branch" "$PREFIX"; then + # we are on a local feature branch already, so $BRANCH must be equal to + # the current branch + avoid_accidental_cross_branch_action || die + fi + + require_clean_working_tree + + if git_branch_exists "$BRANCH"; then + # Again, avoid accidental merges + avoid_accidental_cross_branch_action || die + + # we already have a local branch called like this, so simply pull the + # remote changes in + if flag rebase; then + if ! git_do pull --rebase -q "$REMOTE" "$BRANCH"; then + warn "Pull was aborted. There might be conflicts during rebase or '$REMOTE' might be inaccessible." + exit 1 + fi + else + git_do pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'." + fi + + echo "Pulled $REMOTE's changes into $BRANCH." + else + # setup the local branch clone for the first time + git_do fetch -q "$REMOTE" "$BRANCH" || die "Fetch failed." # stores in FETCH_HEAD + git_do branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed." + git_do checkout -q "$BRANCH" || die "Checking out new local branch failed." + echo "Created local branch $BRANCH based on $REMOTE's $BRANCH." + fi +} diff --git a/ChaosDataPlayer/GSL/bin/git-flow-hotfix b/ChaosDataPlayer/GSL/bin/git-flow-hotfix new file mode 100644 index 0000000..ba485f6 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-hotfix @@ -0,0 +1,349 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +init() { + require_git_repo + require_gitflow_initialized + gitflow_load_settings + VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`") + PREFIX=$(git config --get gitflow.prefix.hotfix) +} + +usage() { + echo "usage: git flow hotfix [list] [-v]" + echo " git flow hotfix start [-F] []" + echo " git flow hotfix finish [-Fsumpk] " + echo " git flow hotfix publish " + echo " git flow hotfix track " +} + +cmd_default() { + cmd_list "$@" +} + +cmd_list() { + DEFINE_boolean verbose false 'verbose (more) output' v + parse_args "$@" + + local hotfix_branches + local current_branch + local short_names + hotfix_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + if [ -z "$hotfix_branches" ]; then + warn "No hotfix branches exist." + warn "" + warn "You can start a new hotfix branch:" + warn "" + warn " git flow hotfix start []" + warn "" + exit 0 + fi + current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g') + short_names=$(echo "$hotfix_branches" | sed "s ^$PREFIX g") + + # determine column width first + local width=0 + local branch + for branch in $short_names; do + local len=${#branch} + width=$(max $width $len) + done + width=$(($width+3)) + + local branch + for branch in $short_names; do + local fullname=$PREFIX$branch + local base=$(git merge-base "$fullname" "$MASTER_BRANCH") + local master_sha=$(git rev-parse "$MASTER_BRANCH") + local branch_sha=$(git rev-parse "$fullname") + if [ "$fullname" = "$current_branch" ]; then + printf "* " + else + printf " " + fi + if flag verbose; then + printf "%-${width}s" "$branch" + if [ "$branch_sha" = "$master_sha" ]; then + printf "(no commits yet)" + else + local tagname=$(git name-rev --tags --no-undefined --name-only "$base") + local nicename + if [ "$tagname" != "" ]; then + nicename=$tagname + else + nicename=$(git rev-parse --short "$base") + fi + printf "(based on $nicename)" + fi + else + printf "%s" "$branch" + fi + echo + done +} + +cmd_help() { + usage + exit 0 +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables + VERSION=$1 + BRANCH=$PREFIX$VERSION +} + +require_version_arg() { + if [ "$VERSION" = "" ]; then + warn "Missing argument " + usage + exit 1 + fi +} + +require_base_is_on_master() { + if ! git branch --no-color --contains "$BASE" 2>/dev/null \ + | sed 's/[* ] //g' \ + | grep -q "^$MASTER_BRANCH\$"; then + die "fatal: Given base '$BASE' is not a valid commit on '$MASTER_BRANCH'." + fi +} + +require_no_existing_hotfix_branches() { + local hotfix_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + local first_branch=$(echo ${hotfix_branches} | head -n1) + first_branch=${first_branch#$PREFIX} + [ -z "$hotfix_branches" ] || \ + die "There is an existing hotfix branch ($first_branch). Finish that one first." +} + +cmd_start() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + parse_args "$@" + BASE=${2:-$MASTER_BRANCH} + require_version_arg + require_base_is_on_master + require_no_existing_hotfix_branches + + # sanity checks + require_clean_working_tree + require_branch_absent "$BRANCH" + require_tag_absent "$VERSION_PREFIX$VERSION" + if flag fetch; then + git_do fetch -q "$ORIGIN" "$MASTER_BRANCH" + fi + if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then + require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH" + fi + + # create branch + git_do checkout -b "$BRANCH" "$BASE" + + echo + echo "Summary of actions:" + echo "- A new branch '$BRANCH' was created, based on '$BASE'" + echo "- You are now on branch '$BRANCH'" + echo + echo "Follow-up actions:" + echo "- Bump the version number now!" + echo "- Start committing your hot fixes" + echo "- When done, run:" + echo + echo " git flow hotfix finish '$VERSION'" + echo +} + +cmd_publish() { + parse_args "$@" + require_version_arg + + # sanity checks + require_clean_working_tree + require_branch "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch_absent "$ORIGIN/$BRANCH" + + # create remote branch + git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH" + git_do fetch -q "$ORIGIN" + + # configure remote tracking + git config "branch.$BRANCH.remote" "$ORIGIN" + git config "branch.$BRANCH.merge" "refs/heads/$BRANCH" + git_do checkout "$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote branch '$BRANCH' was created" + echo "- The local branch '$BRANCH' was configured to track the remote branch" + echo "- You are now on branch '$BRANCH'" + echo +} + +cmd_track() { + parse_args "$@" + require_version_arg + + # sanity checks + require_clean_working_tree + require_branch_absent "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch "$ORIGIN/$BRANCH" + + # create tracking branch + git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote tracking branch '$BRANCH' was created" + echo "- You are now on branch '$BRANCH'" + echo +} + +cmd_finish() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + DEFINE_boolean sign false "sign the release tag cryptographically" s + DEFINE_string signingkey "" "use the given GPG-key for the digital signature (implies -s)" u + DEFINE_string message "" "use the given tag message" m + DEFINE_string messagefile "" "use the contents of the given file as tag message" f + DEFINE_boolean push false "push to $ORIGIN after performing finish" p + DEFINE_boolean keep false "keep branch after performing finish" k + DEFINE_boolean notag false "don't tag this release" n + parse_args "$@" + require_version_arg + + # handle flags that imply other flags + if [ "$FLAGS_signingkey" != "" ]; then + FLAGS_sign=$FLAGS_TRUE + fi + + # sanity checks + require_branch "$BRANCH" + require_clean_working_tree + if flag fetch; then + git_do fetch -q "$ORIGIN" "$MASTER_BRANCH" || \ + die "Could not fetch $MASTER_BRANCH from $ORIGIN." + git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \ + die "Could not fetch $DEVELOP_BRANCH from $ORIGIN." + fi + if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then + require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH" + fi + if has "$ORIGIN/$DEVELOP_BRANCH" $(git_remote_branches); then + require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" + fi + + # try to merge into master + # in case a previous attempt to finish this release branch has failed, + # but the merge into master was successful, we skip it now + if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then + git_do checkout "$MASTER_BRANCH" || \ + die "Could not check out $MASTER_BRANCH." + git_do merge --no-ff "$BRANCH" || \ + die "There were merge conflicts." + # TODO: What do we do now? + fi + + if noflag notag; then + # try to tag the release + # in case a previous attempt to finish this release branch has failed, + # but the tag was set successful, we skip it now + local tagname=$VERSION_PREFIX$VERSION + if ! git_tag_exists "$tagname"; then + local opts="-a" + flag sign && opts="$opts -s" + [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'" + [ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'" + [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'" + eval git_do tag $opts "$VERSION_PREFIX$VERSION" "$BRANCH" || \ + die "Tagging failed. Please run finish again to retry." + fi + fi + + # try to merge into develop + # in case a previous attempt to finish this release branch has failed, + # but the merge into develop was successful, we skip it now + if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then + git_do checkout "$DEVELOP_BRANCH" || \ + die "Could not check out $DEVELOP_BRANCH." + + # TODO: Actually, accounting for 'git describe' pays, so we should + # ideally git merge --no-ff $tagname here, instead! + git_do merge --no-ff "$BRANCH" || \ + die "There were merge conflicts." + # TODO: What do we do now? + fi + + # delete branch + if noflag keep; then + git_do branch -d "$BRANCH" + fi + + if flag push; then + git_do push "$ORIGIN" "$DEVELOP_BRANCH" || \ + die "Could not push to $DEVELOP_BRANCH from $ORIGIN." + git_do push "$ORIGIN" "$MASTER_BRANCH" || \ + die "Could not push to $MASTER_BRANCH from $ORIGIN." + if noflag notag; then + git_do push --tags "$ORIGIN" || \ + die "Could not push tags to $ORIGIN." + fi + fi + + echo + echo "Summary of actions:" + echo "- Latest objects have been fetched from '$ORIGIN'" + echo "- Hotfix branch has been merged into '$MASTER_BRANCH'" + if noflag notag; then + echo "- The hotfix was tagged '$VERSION_PREFIX$VERSION'" + fi + echo "- Hotfix branch has been back-merged into '$DEVELOP_BRANCH'" + if flag keep; then + echo "- Hotfix branch '$BRANCH' is still available" + else + echo "- Hotfix branch '$BRANCH' has been deleted" + fi + if flag push; then + echo "- '$DEVELOP_BRANCH', '$MASTER_BRANCH' and tags have been pushed to '$ORIGIN'" + fi + echo +} diff --git a/ChaosDataPlayer/GSL/bin/git-flow-init b/ChaosDataPlayer/GSL/bin/git-flow-init new file mode 100644 index 0000000..5b4e7e8 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-init @@ -0,0 +1,319 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +usage() { + echo "usage: git flow init [-fd]" +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" +} + +# Default entry when no SUBACTION is given +cmd_default() { + DEFINE_boolean force false 'force setting of gitflow branches, even if already configured' f + DEFINE_boolean defaults false 'use default branch naming conventions' d + parse_args "$@" + + if ! git rev-parse --git-dir >/dev/null 2>&1; then + git_do init + else + # assure that we are not working in a repo with local changes + git_repo_is_headless || require_clean_working_tree + fi + + # running git flow init on an already initialized repo is fine + if gitflow_is_initialized && ! flag force; then + warn "Already initialized for gitflow." + warn "To force reinitialization, use: git flow init -f" + exit 0 + fi + + local branch_count + local answer + + if flag defaults; then + warn "Using default branch names." + fi + + # add a master branch if no such branch exists yet + local master_branch + if gitflow_has_master_configured && ! flag force; then + master_branch=$(git config --get gitflow.branch.master) + else + # Two cases are distinguished: + # 1. A fresh git repo (without any branches) + # We will create a new master/develop branch for the user + # 2. Some branches do already exist + # We will disallow creation of new master/develop branches and + # rather allow to use existing branches for git-flow. + local default_suggestion + local should_check_existence + branch_count=$(git_local_branches | wc -l) + if [ "$branch_count" -eq 0 ]; then + echo "No branches exist yet. Base branches must be created now." + should_check_existence=NO + default_suggestion=$(git config --get gitflow.branch.master || echo master) + else + echo + echo "Which branch should be used for bringing forth production releases?" + git_local_branches | sed 's/^.*$/ - &/g' + + should_check_existence=YES + default_suggestion= + for guess in $(git config --get gitflow.branch.master) \ + 'production' 'main' 'master'; do + if git_local_branch_exists "$guess"; then + default_suggestion="$guess" + break + fi + done + fi + + printf "Branch name for production releases: [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + master_branch=${answer:-$default_suggestion} + + # check existence in case of an already existing repo + if [ "$should_check_existence" = "YES" ]; then + # if no local branch exists and a remote branch of the same + # name exists, checkout that branch and use it for master + if ! git_local_branch_exists "$master_branch" && \ + git_remote_branch_exists "origin/$master_branch"; then + git_do branch "$master_branch" "origin/$master_branch" >/dev/null 2>&1 + elif ! git_local_branch_exists "$master_branch"; then + die "Local branch '$master_branch' does not exist." + fi + fi + + # store the name of the master branch + git_do config gitflow.branch.master "$master_branch" + fi + + # add a develop branch if no such branch exists yet + local develop_branch + if gitflow_has_develop_configured && ! flag force; then + develop_branch=$(git config --get gitflow.branch.develop) + else + # Again, the same two cases as with the master selection are + # considered (fresh repo or repo that contains branches) + local default_suggestion + local should_check_existence + branch_count=$(git_local_branches | grep -v "^${master_branch}\$" | wc -l) + if [ "$branch_count" -eq 0 ]; then + should_check_existence=NO + default_suggestion=$(git config --get gitflow.branch.develop || echo develop) + else + echo + echo "Which branch should be used for integration of the \"next release\"?" + git_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/ - &/g' + + should_check_existence=YES + default_suggestion= + for guess in $(git config --get gitflow.branch.develop) \ + 'develop' 'int' 'integration' 'master'; do + if git_local_branch_exists "$guess" && [ "$guess" != "$master_branch" ]; then + default_suggestion="$guess" + break + fi + done + + if [ -z $default_suggestion ]; then + should_check_existence=NO + default_suggestion=$(git config --get gitflow.branch.develop || echo develop) + fi + + fi + + printf "Branch name for \"next release\" development: [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + develop_branch=${answer:-$default_suggestion} + + if [ "$master_branch" = "$develop_branch" ]; then + die "Production and integration branches should differ." + fi + + # check existence in case of an already existing repo + if [ "$should_check_existence" = "YES" ]; then + git_local_branch_exists "$develop_branch" || \ + die "Local branch '$develop_branch' does not exist." + fi + + # store the name of the develop branch + git_do config gitflow.branch.develop "$develop_branch" + fi + + # Creation of HEAD + # ---------------- + # We create a HEAD now, if it does not exist yet (in a fresh repo). We need + # it to be able to create new branches. + local created_gitflow_branch=0 + if ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1; then + git_do symbolic-ref HEAD "refs/heads/$master_branch" + git_do commit --allow-empty --quiet -m "Initial commit" + created_gitflow_branch=1 + fi + + # Creation of master + # ------------------ + # At this point, there always is a master branch: either it existed already + # (and was picked interactively as the production branch) or it has just + # been created in a fresh repo + + # Creation of develop + # ------------------- + # The develop branch possibly does not exist yet. This is the case when, + # in a git init'ed repo with one or more commits, master was picked as the + # default production branch and develop was "created". We should create + # the develop branch now in that case (we base it on master, of course) + if ! git_local_branch_exists "$develop_branch"; then + if git_remote_branch_exists "origin/$develop_branch"; then + git_do branch "$develop_branch" "origin/$develop_branch" >/dev/null 2>&1 + else + git_do branch --no-track "$develop_branch" "$master_branch" + fi + created_gitflow_branch=1 + fi + + # assert the gitflow repo has been correctly initialized + gitflow_is_initialized + + # switch to develop branch if its newly created + if [ $created_gitflow_branch -eq 1 ]; then + git_do checkout -q "$develop_branch" + fi + + # finally, ask the user for naming conventions (branch and tag prefixes) + if flag force || \ + ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || + ! git config --get gitflow.prefix.release >/dev/null 2>&1 || + ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || + ! git config --get gitflow.prefix.support >/dev/null 2>&1 || + ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1; then + echo + echo "How to name your supporting branch prefixes?" + fi + + local prefix + + # Feature branches + if ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || flag force; then + default_suggestion=$(git config --get gitflow.prefix.feature || echo feature/) + printf "Feature branches? [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} + git_do config gitflow.prefix.feature "$prefix" + fi + + # Release branches + if ! git config --get gitflow.prefix.release >/dev/null 2>&1 || flag force; then + default_suggestion=$(git config --get gitflow.prefix.release || echo release/) + printf "Release branches? [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} + git_do config gitflow.prefix.release "$prefix" + fi + + + # Hotfix branches + if ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || flag force; then + default_suggestion=$(git config --get gitflow.prefix.hotfix || echo hotfix/) + printf "Hotfix branches? [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} + git_do config gitflow.prefix.hotfix "$prefix" + fi + + + # Support branches + if ! git config --get gitflow.prefix.support >/dev/null 2>&1 || flag force; then + default_suggestion=$(git config --get gitflow.prefix.support || echo support/) + printf "Support branches? [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} + git_do config gitflow.prefix.support "$prefix" + fi + + + # Version tag prefix + if ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1 || flag force; then + default_suggestion=$(git config --get gitflow.prefix.versiontag || echo "") + printf "Version tag prefix? [$default_suggestion] " + if noflag defaults; then + read answer + else + printf "\n" + fi + [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} + git_do config gitflow.prefix.versiontag "$prefix" + fi + + + # TODO: what to do with origin? +} + +cmd_help() { + usage + exit 0 +} diff --git a/ChaosDataPlayer/GSL/bin/git-flow-release b/ChaosDataPlayer/GSL/bin/git-flow-release new file mode 100644 index 0000000..cb95bd4 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-release @@ -0,0 +1,365 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +init() { + require_git_repo + require_gitflow_initialized + gitflow_load_settings + VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`") + PREFIX=$(git config --get gitflow.prefix.release) +} + +usage() { + echo "usage: git flow release [list] [-v]" + echo " git flow release start [-F] []" + echo " git flow release finish [-FsumpkS] " + echo " git flow release publish " + echo " git flow release track " +} + +cmd_default() { + cmd_list "$@" +} + +cmd_list() { + DEFINE_boolean verbose false 'verbose (more) output' v + parse_args "$@" + + local release_branches + local current_branch + local short_names + release_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + if [ -z "$release_branches" ]; then + warn "No release branches exist." + warn "" + warn "You can start a new release branch:" + warn "" + warn " git flow release start []" + warn "" + exit 0 + fi + + current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g') + short_names=$(echo "$release_branches" | sed "s ^$PREFIX g") + + # determine column width first + local width=0 + local branch + for branch in $short_names; do + local len=${#branch} + width=$(max $width $len) + done + width=$(($width+3)) + + local branch + for branch in $short_names; do + local fullname=$PREFIX$branch + local base=$(git merge-base "$fullname" "$DEVELOP_BRANCH") + local develop_sha=$(git rev-parse "$DEVELOP_BRANCH") + local branch_sha=$(git rev-parse "$fullname") + if [ "$fullname" = "$current_branch" ]; then + printf "* " + else + printf " " + fi + if flag verbose; then + printf "%-${width}s" "$branch" + if [ "$branch_sha" = "$develop_sha" ]; then + printf "(no commits yet)" + else + local nicename=$(git rev-parse --short "$base") + printf "(based on $nicename)" + fi + else + printf "%s" "$branch" + fi + echo + done +} + +cmd_help() { + usage + exit 0 +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables + VERSION=$1 + BRANCH=$PREFIX$VERSION +} + +require_version_arg() { + if [ "$VERSION" = "" ]; then + warn "Missing argument " + usage + exit 1 + fi +} + +require_base_is_on_develop() { + if ! git_do branch --no-color --contains "$BASE" 2>/dev/null \ + | sed 's/[* ] //g' \ + | grep -q "^$DEVELOP_BRANCH\$"; then + die "fatal: Given base '$BASE' is not a valid commit on '$DEVELOP_BRANCH'." + fi +} + +require_no_existing_release_branches() { + local release_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + local first_branch=$(echo ${release_branches} | head -n1) + first_branch=${first_branch#$PREFIX} + [ -z "$release_branches" ] || \ + die "There is an existing release branch ($first_branch). Finish that one first." +} + +cmd_start() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + parse_args "$@" + BASE=${2:-$DEVELOP_BRANCH} + require_version_arg + require_base_is_on_develop + require_no_existing_release_branches + + # sanity checks + require_clean_working_tree + require_branch_absent "$BRANCH" + require_tag_absent "$VERSION_PREFIX$VERSION" + if flag fetch; then + git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" + fi + if has "$ORIGIN/$DEVELOP_BRANCH" $(git_remote_branches); then + require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" + fi + + # create branch + git_do checkout -b "$BRANCH" "$BASE" + + echo + echo "Summary of actions:" + echo "- A new branch '$BRANCH' was created, based on '$BASE'" + echo "- You are now on branch '$BRANCH'" + echo + echo "Follow-up actions:" + echo "- Bump the version number now!" + echo "- Start committing last-minute fixes in preparing your release" + echo "- When done, run:" + echo + echo " git flow release finish '$VERSION'" + echo +} + +cmd_finish() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + DEFINE_boolean sign false "sign the release tag cryptographically" s + DEFINE_string signingkey "" "use the given GPG-key for the digital signature (implies -s)" u + DEFINE_string message "" "use the given tag message" m + DEFINE_string messagefile "" "use the contents of the given file as a tag message" f + DEFINE_boolean push false "push to $ORIGIN after performing finish" p + DEFINE_boolean keep false "keep branch after performing finish" k + DEFINE_boolean notag false "don't tag this release" n + DEFINE_boolean squash false "squash release during merge" S + + parse_args "$@" + require_version_arg + + # handle flags that imply other flags + if [ "$FLAGS_signingkey" != "" ]; then + FLAGS_sign=$FLAGS_TRUE + fi + + # sanity checks + require_branch "$BRANCH" + require_clean_working_tree + if flag fetch; then + git_do fetch -q "$ORIGIN" "$MASTER_BRANCH" || \ + die "Could not fetch $MASTER_BRANCH from $ORIGIN." + git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \ + die "Could not fetch $DEVELOP_BRANCH from $ORIGIN." + fi + if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then + require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH" + fi + if has "$ORIGIN/$DEVELOP_BRANCH" $(git_remote_branches); then + require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH" + fi + + # try to merge into master + # in case a previous attempt to finish this release branch has failed, + # but the merge into master was successful, we skip it now + if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then + git_do checkout "$MASTER_BRANCH" || \ + die "Could not check out $MASTER_BRANCH." + if noflag squash; then + git_do merge --no-ff "$BRANCH" || \ + die "There were merge conflicts." + # TODO: What do we do now? + else + git_do merge --squash "$BRANCH" || \ + die "There were merge conflicts." + git_do commit + fi + fi + + if noflag notag; then + # try to tag the release + # in case a previous attempt to finish this release branch has failed, + # but the tag was set successful, we skip it now + local tagname=$VERSION_PREFIX$VERSION + if ! git_tag_exists "$tagname"; then + local opts="-a" + flag sign && opts="$opts -s" + [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'" + [ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'" + [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'" + eval git_do tag $opts "$tagname" "$BRANCH" || \ + die "Tagging failed. Please run finish again to retry." + fi + fi + + # try to merge into develop + # in case a previous attempt to finish this release branch has failed, + # but the merge into develop was successful, we skip it now + if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then + git_do checkout "$DEVELOP_BRANCH" || \ + die "Could not check out $DEVELOP_BRANCH." + + # TODO: Actually, accounting for 'git describe' pays, so we should + # ideally git merge --no-ff $tagname here, instead! + if noflag squash; then + git_do merge --no-ff "$BRANCH" || \ + die "There were merge conflicts." + # TODO: What do we do now? + else + git_do merge --squash "$BRANCH" || \ + die "There were merge conflicts." + # TODO: What do we do now? + git_do commit + fi + fi + + # delete branch + if noflag keep; then + if [ "$BRANCH" = "$(git_current_branch)" ]; then + git_do checkout "$MASTER_BRANCH" + fi + git_do branch -d "$BRANCH" + fi + + if flag push; then + git_do push "$ORIGIN" "$DEVELOP_BRANCH" || \ + die "Could not push to $DEVELOP_BRANCH from $ORIGIN." + git_do push "$ORIGIN" "$MASTER_BRANCH" || \ + die "Could not push to $MASTER_BRANCH from $ORIGIN." + if noflag notag; then + git_do push --tags "$ORIGIN" || \ + die "Could not push tags to $ORIGIN." + fi + git_do push "$ORIGIN" :"$BRANCH" || \ + die "Could not delete the remote $BRANCH in $ORIGIN." + fi + + echo + echo "Summary of actions:" + echo "- Latest objects have been fetched from '$ORIGIN'" + echo "- Release branch has been merged into '$MASTER_BRANCH'" + if noflag notag; then + echo "- The release was tagged '$tagname'" + fi + echo "- Release branch has been back-merged into '$DEVELOP_BRANCH'" + if flag keep; then + echo "- Release branch '$BRANCH' is still available" + else + echo "- Release branch '$BRANCH' has been deleted" + fi + if flag push; then + echo "- '$DEVELOP_BRANCH', '$MASTER_BRANCH' and tags have been pushed to '$ORIGIN'" + echo "- Release branch '$BRANCH' in '$ORIGIN' has been deleted." + fi + echo +} + +cmd_publish() { + parse_args "$@" + require_version_arg + + # sanity checks + require_clean_working_tree + require_branch "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch_absent "$ORIGIN/$BRANCH" + + # create remote branch + git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH" + git_do fetch -q "$ORIGIN" + + # configure remote tracking + git_do config "branch.$BRANCH.remote" "$ORIGIN" + git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH" + git_do checkout "$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote branch '$BRANCH' was created" + echo "- The local branch '$BRANCH' was configured to track the remote branch" + echo "- You are now on branch '$BRANCH'" + echo +} + +cmd_track() { + parse_args "$@" + require_version_arg + + # sanity checks + require_clean_working_tree + require_branch_absent "$BRANCH" + git_do fetch -q "$ORIGIN" + require_branch "$ORIGIN/$BRANCH" + + # create tracking branch + git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH" + + echo + echo "Summary of actions:" + echo "- A new remote tracking branch '$BRANCH' was created" + echo "- You are now on branch '$BRANCH'" + echo +} diff --git a/ChaosDataPlayer/GSL/bin/git-flow-support b/ChaosDataPlayer/GSL/bin/git-flow-support new file mode 100644 index 0000000..cdbfc71 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-support @@ -0,0 +1,184 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +init() { + require_git_repo + require_gitflow_initialized + gitflow_load_settings + VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`") + PREFIX=$(git config --get gitflow.prefix.support) +} + +warn "note: The support subcommand is still very EXPERIMENTAL!" +warn "note: DO NOT use it in a production situation." + +usage() { + echo "usage: git flow support [list] [-v]" + echo " git flow support start [-F] " +} + +cmd_default() { + cmd_list "$@" +} + +cmd_list() { + DEFINE_boolean verbose false 'verbose (more) output' v + parse_args "$@" + + local support_branches + local current_branch + local short_names + support_branches=$(echo "$(git_local_branches)" | grep "^$PREFIX") + if [ -z "$support_branches" ]; then + warn "No support branches exist." + warn "" + warn "You can start a new support branch:" + warn "" + warn " git flow support start " + warn "" + exit 0 + fi + current_branch=$(git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g') + short_names=$(echo "$support_branches" | sed "s ^$PREFIX g") + + # determine column width first + local width=0 + local branch + for branch in $short_names; do + local len=${#branch} + width=$(max $width $len) + done + width=$(($width+3)) + + local branch + for branch in $short_names; do + local fullname=$PREFIX$branch + local base=$(git merge-base "$fullname" "$MASTER_BRANCH") + local master_sha=$(git rev-parse "$MASTER_BRANCH") + local branch_sha=$(git rev-parse "$fullname") + if [ "$fullname" = "$current_branch" ]; then + printf "* " + else + printf " " + fi + if flag verbose; then + printf "%-${width}s" "$branch" + if [ "$branch_sha" = "$master_sha" ]; then + printf "(no commits yet)" + else + local tagname=$(git name-rev --tags --no-undefined --name-only "$base") + local nicename + if [ "$tagname" != "" ]; then + nicename=$tagname + else + nicename=$(git rev-parse --short "$base") + fi + printf "(based on $nicename)" + fi + else + printf "%s" "$branch" + fi + echo + done +} + +cmd_help() { + usage + exit 0 +} + +parse_args() { + # parse options + FLAGS "$@" || exit $? + eval set -- "${FLAGS_ARGV}" + + # read arguments into global variables + VERSION=$1 + BASE=$2 + BRANCH=$PREFIX$VERSION +} + +require_version_arg() { + if [ "$VERSION" = "" ]; then + warn "Missing argument " + usage + exit 1 + fi +} + +require_base_arg() { + if [ "$BASE" = "" ]; then + warn "Missing argument " + usage + exit 1 + fi +} + +require_base_is_on_master() { + if ! git branch --no-color --contains "$BASE" 2>/dev/null \ + | sed 's/[* ] //g' \ + | grep -q "^$MASTER_BRANCH\$"; then + die "fatal: Given base '$BASE' is not a valid commit on '$MASTER_BRANCH'." + fi +} + +cmd_start() { + DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F + parse_args "$@" + require_version_arg + require_base_arg + require_base_is_on_master + + # sanity checks + require_clean_working_tree + + # fetch remote changes + if flag fetch; then + git_do fetch -q "$ORIGIN" "$BASE" + fi + require_branch_absent "$BRANCH" + + # create branch + git_do checkout -b "$BRANCH" "$BASE" + + echo + echo "Summary of actions:" + echo "- A new branch '$BRANCH' was created, based on '$BASE'" + echo "- You are now on branch '$BRANCH'" + echo +} diff --git a/ChaosDataPlayer/GSL/bin/git-flow-version b/ChaosDataPlayer/GSL/bin/git-flow-version new file mode 100644 index 0000000..8c31499 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/git-flow-version @@ -0,0 +1,52 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +GITFLOW_VERSION=0.4.2-pre + +usage() { + echo "usage: git flow version" +} + +cmd_default() { + echo "$GITFLOW_VERSION" +} + +cmd_help() { + usage + exit 0 +} diff --git a/ChaosDataPlayer/GSL/bin/gitflow-common b/ChaosDataPlayer/GSL/bin/gitflow-common new file mode 100644 index 0000000..3327405 --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/gitflow-common @@ -0,0 +1,326 @@ +# +# git-flow -- A collection of Git extensions to provide high-level +# repository operations for Vincent Driessen's branching model. +# +# Original blog post presenting this model is found at: +# http://nvie.com/git-model +# +# Feel free to contribute to this project at: +# http://github.com/nvie/gitflow +# +# Copyright 2010 Vincent Driessen. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are +# those of the authors and should not be interpreted as representing official +# policies, either expressed or implied, of Vincent Driessen. +# + +# +# Common functionality +# + +# shell output +warn() { echo "$@" >&2; } +die() { warn "$@"; exit 1; } + +escape() { + echo "$1" | sed 's/\([\.\$\*]\)/\\\1/g' +} + +# set logic +has() { + local item=$1; shift + echo " $@ " | grep -q " $(escape $item) " +} + +# basic math +min() { [ "$1" -le "$2" ] && echo "$1" || echo "$2"; } +max() { [ "$1" -ge "$2" ] && echo "$1" || echo "$2"; } + +# basic string matching +startswith() { [ "$1" != "${1#$2}" ]; } +endswith() { [ "$1" != "${1%$2}" ]; } + +# convenience functions for checking shFlags flags +flag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -eq $FLAGS_TRUE ]; } +noflag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -ne $FLAGS_TRUE ]; } + +# +# Git specific common functionality +# + +git_do() { + # equivalent to git, used to indicate actions that make modifications + if flag show_commands; then + echo "git $@" >&2 + fi + git "$@" +} + +git_local_branches() { git branch --no-color | sed 's/^[* ] //'; } +git_remote_branches() { git branch -r --no-color | sed 's/^[* ] //'; } +git_all_branches() { ( git branch --no-color; git branch -r --no-color) | sed 's/^[* ] //'; } +git_all_tags() { git tag; } + +git_current_branch() { + git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g' +} + +git_is_clean_working_tree() { + if ! git diff --no-ext-diff --ignore-submodules --quiet --exit-code; then + return 1 + elif ! git diff-index --cached --quiet --ignore-submodules HEAD --; then + return 2 + else + return 0 + fi +} + +git_repo_is_headless() { + ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1 +} + +git_local_branch_exists() { + has $1 $(git_local_branches) +} + +git_remote_branch_exists() { + has $1 $(git_remote_branches) +} + +git_branch_exists() { + has $1 $(git_all_branches) +} + +git_tag_exists() { + has $1 $(git_all_tags) +} + +# +# git_compare_branches() +# +# Tests whether branches and their "origin" counterparts have diverged and need +# merging first. It returns error codes to provide more detail, like so: +# +# 0 Branch heads point to the same commit +# 1 First given branch needs fast-forwarding +# 2 Second given branch needs fast-forwarding +# 3 Branch needs a real merge +# 4 There is no merge base, i.e. the branches have no common ancestors +# +git_compare_branches() { + local commit1=$(git rev-parse "$1") + local commit2=$(git rev-parse "$2") + if [ "$commit1" != "$commit2" ]; then + local base=$(git merge-base "$commit1" "$commit2") + if [ $? -ne 0 ]; then + return 4 + elif [ "$commit1" = "$base" ]; then + return 1 + elif [ "$commit2" = "$base" ]; then + return 2 + else + return 3 + fi + else + return 0 + fi +} + +# +# git_is_branch_merged_into() +# +# Checks whether branch $1 is succesfully merged into $2 +# +git_is_branch_merged_into() { + local subject=$1 + local base=$2 + local all_merges="$(git branch --no-color --contains $subject | sed 's/^[* ] //')" + has $base $all_merges +} + +# +# gitflow specific common functionality +# + +# check if this repo has been inited for gitflow +gitflow_has_master_configured() { + local master=$(git config --get gitflow.branch.master) + [ "$master" != "" ] && git_local_branch_exists "$master" +} + +gitflow_has_develop_configured() { + local develop=$(git config --get gitflow.branch.develop) + [ "$develop" != "" ] && git_local_branch_exists "$develop" +} + +gitflow_has_prefixes_configured() { + git config --get gitflow.prefix.feature >/dev/null 2>&1 && \ + git config --get gitflow.prefix.release >/dev/null 2>&1 && \ + git config --get gitflow.prefix.hotfix >/dev/null 2>&1 && \ + git config --get gitflow.prefix.support >/dev/null 2>&1 && \ + git config --get gitflow.prefix.versiontag >/dev/null 2>&1 +} + +gitflow_is_initialized() { + gitflow_has_master_configured && \ + gitflow_has_develop_configured && \ + [ "$(git config --get gitflow.branch.master)" != \ + "$(git config --get gitflow.branch.develop)" ] && \ + gitflow_has_prefixes_configured +} + +# loading settings that can be overridden using git config +gitflow_load_settings() { + export DOT_GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) + export MASTER_BRANCH=$(git config --get gitflow.branch.master) + export DEVELOP_BRANCH=$(git config --get gitflow.branch.develop) + export ORIGIN=$(git config --get gitflow.origin || echo origin) +} + +# +# gitflow_resolve_nameprefix +# +# Inputs: +# $1 = name prefix to resolve +# $2 = branch prefix to use +# +# Searches branch names from git_local_branches() to look for a unique +# branch name whose name starts with the given name prefix. +# +# There are multiple exit codes possible: +# 0: The unambiguous full name of the branch is written to stdout +# (success) +# 1: No match is found. +# 2: Multiple matches found. These matches are written to stderr +# +gitflow_resolve_nameprefix() { + local name=$1 + local prefix=$2 + local matches + local num_matches + + # first, check if there is a perfect match + if git_local_branch_exists "$prefix$name"; then + echo "$name" + return 0 + fi + + matches=$(echo "$(git_local_branches)" | grep "^$(escape "$prefix$name")") + num_matches=$(echo "$matches" | wc -l) + if [ -z "$matches" ]; then + # no prefix match, so take it literally + warn "No branch matches prefix '$name'" + return 1 + else + if [ $num_matches -eq 1 ]; then + echo "${matches#$prefix}" + return 0 + else + # multiple matches, cannot decide + warn "Multiple branches match prefix '$name':" + for match in $matches; do + warn "- $match" + done + return 2 + fi + fi +} + +# +# Assertions for use in git-flow subcommands +# + +require_git_repo() { + if ! git rev-parse --git-dir >/dev/null 2>&1; then + die "fatal: Not a git repository" + fi +} + +require_gitflow_initialized() { + if ! gitflow_is_initialized; then + die "fatal: Not a gitflow-enabled repo yet. Please run \"git flow init\" first." + fi +} + +require_clean_working_tree() { + git_is_clean_working_tree + local result=$? + if [ $result -eq 1 ]; then + die "fatal: Working tree contains unstaged changes. Aborting." + fi + if [ $result -eq 2 ]; then + die "fatal: Index contains uncommited changes. Aborting." + fi +} + +require_local_branch() { + if ! git_local_branch_exists $1; then + die "fatal: Local branch '$1' does not exist and is required." + fi +} + +require_remote_branch() { + if ! has $1 $(git_remote_branches); then + die "Remote branch '$1' does not exist and is required." + fi +} + +require_branch() { + if ! has $1 $(git_all_branches); then + die "Branch '$1' does not exist and is required." + fi +} + +require_branch_absent() { + if has $1 $(git_all_branches); then + die "Branch '$1' already exists. Pick another name." + fi +} + +require_tag_absent() { + for tag in $(git_all_tags); do + if [ "$1" = "$tag" ]; then + die "Tag '$1' already exists. Pick another name." + fi + done +} + +require_branches_equal() { + require_local_branch "$1" + require_remote_branch "$2" + git_compare_branches "$1" "$2" + local status=$? + if [ $status -gt 0 ]; then + warn "Branches '$1' and '$2' have diverged." + if [ $status -eq 1 ]; then + die "And branch '$1' may be fast-forwarded." + elif [ $status -eq 2 ]; then + # Warn here, since there is no harm in being ahead + warn "And local branch '$1' is ahead of '$2'." + else + die "Branches need merging first." + fi + fi +} diff --git a/ChaosDataPlayer/GSL/bin/gsl-config b/ChaosDataPlayer/GSL/bin/gsl-config new file mode 100644 index 0000000..f1bb52d --- /dev/null +++ b/ChaosDataPlayer/GSL/bin/gsl-config @@ -0,0 +1,80 @@ +#! /bin/sh + +prefix=/usr/local +exec_prefix=/usr/local +includedir=/usr/local/include + +usage() +{ + cat <: contains value of flag named 'flag_name' +# __flags__default: the default flag value +# __flags__help: the flag help string +# __flags__short: the flag short name +# __flags__type: the flag type +# +# Notes: +# - lists of strings are space separated, and a null value is the '~' char. + +# return if FLAGS already loaded +[ -n "${FLAGS_VERSION:-}" ] && return 0 + +FLAGS_VERSION='1.0.4pre' + +# a user can set the path to a different getopt command by overriding this +# variable in their script +FLAGS_GETOPT_CMD=${FLAGS_GETOPT_CMD:-getopt} + +# return values that scripts can use +FLAGS_TRUE=0 +FLAGS_FALSE=1 +FLAGS_ERROR=2 + +# logging functions +_flags_debug() { echo "flags:DEBUG $@" >&2; } +_flags_warn() { echo "flags:WARN $@" >&2; } +_flags_error() { echo "flags:ERROR $@" >&2; } +_flags_fatal() { echo "flags:FATAL $@" >&2; exit ${FLAGS_ERROR}; } + +# specific shell checks +if [ -n "${ZSH_VERSION:-}" ]; then + setopt |grep "^shwordsplit$" >/dev/null + if [ $? -ne ${FLAGS_TRUE} ]; then + _flags_fatal 'zsh shwordsplit option is required for proper zsh operation' + fi + if [ -z "${FLAGS_PARENT:-}" ]; then + _flags_fatal "zsh does not pass \$0 through properly. please declare' \ +\"FLAGS_PARENT=\$0\" before calling shFlags" + fi +fi + +# +# constants +# + +# reserved flag names +__FLAGS_RESERVED_LIST=' ARGC ARGV ERROR FALSE GETOPT_CMD HELP PARENT TRUE ' +__FLAGS_RESERVED_LIST="${__FLAGS_RESERVED_LIST} VERSION " + +# getopt version +__FLAGS_GETOPT_VERS_STD=0 +__FLAGS_GETOPT_VERS_ENH=1 +__FLAGS_GETOPT_VERS_BSD=2 + +${FLAGS_GETOPT_CMD} >/dev/null 2>&1 +case $? in + 0) __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} ;; # bsd getopt + 2) + # TODO(kward): look into '-T' option to test the internal getopt() version + if [ "`${FLAGS_GETOPT_CMD} --version`" = '-- ' ]; then + __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} + else + __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_ENH} + fi + ;; + *) _flags_fatal 'unable to determine getopt version' ;; +esac + +# getopt optstring lengths +__FLAGS_OPTSTR_SHORT=0 +__FLAGS_OPTSTR_LONG=1 + +__FLAGS_NULL='~' + +# flag info strings +__FLAGS_INFO_DEFAULT='default' +__FLAGS_INFO_HELP='help' +__FLAGS_INFO_SHORT='short' +__FLAGS_INFO_TYPE='type' + +# flag lengths +__FLAGS_LEN_SHORT=0 +__FLAGS_LEN_LONG=1 + +# flag types +__FLAGS_TYPE_NONE=0 +__FLAGS_TYPE_BOOLEAN=1 +__FLAGS_TYPE_FLOAT=2 +__FLAGS_TYPE_INTEGER=3 +__FLAGS_TYPE_STRING=4 + +# set the constants readonly +__flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'` +for __flags_const in ${__flags_constants}; do + # skip certain flags + case ${__flags_const} in + FLAGS_HELP) continue ;; + FLAGS_PARENT) continue ;; + esac + # set flag readonly + if [ -z "${ZSH_VERSION:-}" ]; then + readonly ${__flags_const} + else # handle zsh + case ${ZSH_VERSION} in + [123].*) readonly ${__flags_const} ;; + *) readonly -g ${__flags_const} ;; # declare readonly constants globally + esac + fi +done +unset __flags_const __flags_constants + +# +# internal variables +# + +# space separated lists +__flags_boolNames=' ' # boolean flag names +__flags_longNames=' ' # long flag names +__flags_shortNames=' ' # short flag names +__flags_definedNames=' ' # defined flag names (used for validation) + +__flags_columns='' # screen width in columns +__flags_opts='' # temporary storage for parsed getopt flags + +#------------------------------------------------------------------------------ +# private functions +# + +# Define a flag. +# +# Calling this function will define the following info variables for the +# specified flag: +# FLAGS_flagname - the name for this flag (based upon the long flag name) +# __flags__default - the default value +# __flags_flagname_help - the help string +# __flags_flagname_short - the single letter alias +# __flags_flagname_type - the type of flag (one of __FLAGS_TYPE_*) +# +# Args: +# _flags__type: integer: internal type of flag (__FLAGS_TYPE_*) +# _flags__name: string: long flag name +# _flags__default: default flag value +# _flags__help: string: help string +# _flags__short: string: (optional) short flag name +# Returns: +# integer: success of operation, or error +_flags_define() +{ + if [ $# -lt 4 ]; then + flags_error='DEFINE error: too few arguments' + flags_return=${FLAGS_ERROR} + _flags_error "${flags_error}" + return ${flags_return} + fi + + _flags_type_=$1 + _flags_name_=$2 + _flags_default_=$3 + _flags_help_=$4 + _flags_short_=${5:-${__FLAGS_NULL}} + + _flags_return_=${FLAGS_TRUE} + _flags_usName_=`_flags_underscoreName ${_flags_name_}` + + # check whether the flag name is reserved + _flags_itemInList ${_flags_usName_} "${__FLAGS_RESERVED_LIST}" + if [ $? -eq ${FLAGS_TRUE} ]; then + flags_error="flag name (${_flags_name_}) is reserved" + _flags_return_=${FLAGS_ERROR} + fi + + # require short option for getopt that don't support long options + if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ + -a ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} \ + -a "${_flags_short_}" = "${__FLAGS_NULL}" ] + then + flags_error="short flag required for (${_flags_name_}) on this platform" + _flags_return_=${FLAGS_ERROR} + fi + + # check for existing long name definition + if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then + if _flags_itemInList ${_flags_usName_} ${__flags_definedNames}; then + flags_error="definition for ([no]${_flags_name_}) already exists" + _flags_warn "${flags_error}" + _flags_return_=${FLAGS_FALSE} + fi + fi + + # check for existing short name definition + if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ + -a "${_flags_short_}" != "${__FLAGS_NULL}" ] + then + if _flags_itemInList "${_flags_short_}" ${__flags_shortNames}; then + flags_error="flag short name (${_flags_short_}) already defined" + _flags_warn "${flags_error}" + _flags_return_=${FLAGS_FALSE} + fi + fi + + # handle default value. note, on several occasions the 'if' portion of an + # if/then/else contains just a ':' which does nothing. a binary reversal via + # '!' is not done because it does not work on all shells. + if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then + case ${_flags_type_} in + ${__FLAGS_TYPE_BOOLEAN}) + if _flags_validateBoolean "${_flags_default_}"; then + case ${_flags_default_} in + true|t|0) _flags_default_=${FLAGS_TRUE} ;; + false|f|1) _flags_default_=${FLAGS_FALSE} ;; + esac + else + flags_error="invalid default flag value '${_flags_default_}'" + _flags_return_=${FLAGS_ERROR} + fi + ;; + + ${__FLAGS_TYPE_FLOAT}) + if _flags_validateFloat "${_flags_default_}"; then + : + else + flags_error="invalid default flag value '${_flags_default_}'" + _flags_return_=${FLAGS_ERROR} + fi + ;; + + ${__FLAGS_TYPE_INTEGER}) + if _flags_validateInteger "${_flags_default_}"; then + : + else + flags_error="invalid default flag value '${_flags_default_}'" + _flags_return_=${FLAGS_ERROR} + fi + ;; + + ${__FLAGS_TYPE_STRING}) ;; # everything in shell is a valid string + + *) + flags_error="unrecognized flag type '${_flags_type_}'" + _flags_return_=${FLAGS_ERROR} + ;; + esac + fi + + if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then + # store flag information + eval "FLAGS_${_flags_usName_}='${_flags_default_}'" + eval "__flags_${_flags_usName_}_${__FLAGS_INFO_TYPE}=${_flags_type_}" + eval "__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}=\ +\"${_flags_default_}\"" + eval "__flags_${_flags_usName_}_${__FLAGS_INFO_HELP}=\"${_flags_help_}\"" + eval "__flags_${_flags_usName_}_${__FLAGS_INFO_SHORT}='${_flags_short_}'" + + # append flag names to name lists + __flags_shortNames="${__flags_shortNames}${_flags_short_} " + __flags_longNames="${__flags_longNames}${_flags_name_} " + [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \ + __flags_boolNames="${__flags_boolNames}no${_flags_name_} " + + # append flag names to defined names for later validation checks + __flags_definedNames="${__flags_definedNames}${_flags_usName_} " + [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \ + __flags_definedNames="${__flags_definedNames}no${_flags_usName_} " + fi + + flags_return=${_flags_return_} + unset _flags_default_ _flags_help_ _flags_name_ _flags_return_ \ + _flags_short_ _flags_type_ _flags_usName_ + [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}" + return ${flags_return} +} + +# Underscore a flag name by replacing dashes with underscores. +# +# Args: +# unnamed: string: log flag name +# Output: +# string: underscored name +_flags_underscoreName() +{ + echo $1 |tr '-' '_' +} + +# Return valid getopt options using currently defined list of long options. +# +# This function builds a proper getopt option string for short (and long) +# options, using the current list of long options for reference. +# +# Args: +# _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*) +# Output: +# string: generated option string for getopt +# Returns: +# boolean: success of operation (always returns True) +_flags_genOptStr() +{ + _flags_optStrType_=$1 + + _flags_opts_='' + + for _flags_name_ in ${__flags_longNames}; do + _flags_usName_=`_flags_underscoreName ${_flags_name_}` + _flags_type_=`_flags_getFlagInfo ${_flags_usName_} ${__FLAGS_INFO_TYPE}` + [ $? -eq ${FLAGS_TRUE} ] || _flags_fatal 'call to _flags_type_ failed' + case ${_flags_optStrType_} in + ${__FLAGS_OPTSTR_SHORT}) + _flags_shortName_=`_flags_getFlagInfo \ + ${_flags_usName_} ${__FLAGS_INFO_SHORT}` + if [ "${_flags_shortName_}" != "${__FLAGS_NULL}" ]; then + _flags_opts_="${_flags_opts_}${_flags_shortName_}" + # getopt needs a trailing ':' to indicate a required argument + [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \ + _flags_opts_="${_flags_opts_}:" + fi + ;; + + ${__FLAGS_OPTSTR_LONG}) + _flags_opts_="${_flags_opts_:+${_flags_opts_},}${_flags_name_}" + # getopt needs a trailing ':' to indicate a required argument + [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \ + _flags_opts_="${_flags_opts_}:" + ;; + esac + done + + echo "${_flags_opts_}" + unset _flags_name_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \ + _flags_type_ _flags_usName_ + return ${FLAGS_TRUE} +} + +# Returns flag details based on a flag name and flag info. +# +# Args: +# string: underscored flag name +# string: flag info (see the _flags_define function for valid info types) +# Output: +# string: value of dereferenced flag variable +# Returns: +# integer: one of FLAGS_{TRUE|FALSE|ERROR} +_flags_getFlagInfo() +{ + # note: adding gFI to variable names to prevent naming conflicts with calling + # functions + _flags_gFI_usName_=$1 + _flags_gFI_info_=$2 + + _flags_infoVar_="__flags_${_flags_gFI_usName_}_${_flags_gFI_info_}" + _flags_strToEval_="_flags_infoValue_=\"\${${_flags_infoVar_}:-}\"" + eval "${_flags_strToEval_}" + if [ -n "${_flags_infoValue_}" ]; then + flags_return=${FLAGS_TRUE} + else + # see if the _flags_gFI_usName_ variable is a string as strings can be + # empty... + # note: the DRY principle would say to have this function call itself for + # the next three lines, but doing so results in an infinite loop as an + # invalid _flags_name_ will also not have the associated _type variable. + # Because it doesn't (it will evaluate to an empty string) the logic will + # try to find the _type variable of the _type variable, and so on. Not so + # good ;-) + _flags_typeVar_="__flags_${_flags_gFI_usName_}_${__FLAGS_INFO_TYPE}" + _flags_strToEval_="_flags_typeValue_=\"\${${_flags_typeVar_}:-}\"" + eval "${_flags_strToEval_}" + if [ "${_flags_typeValue_}" = "${__FLAGS_TYPE_STRING}" ]; then + flags_return=${FLAGS_TRUE} + else + flags_return=${FLAGS_ERROR} + flags_error="missing flag info variable (${_flags_infoVar_})" + fi + fi + + echo "${_flags_infoValue_}" + unset _flags_gFI_usName_ _flags_gfI_info_ _flags_infoValue_ _flags_infoVar_ \ + _flags_strToEval_ _flags_typeValue_ _flags_typeVar_ + [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}" + return ${flags_return} +} + +# Check for presense of item in a list. +# +# Passed a string (e.g. 'abc'), this function will determine if the string is +# present in the list of strings (e.g. ' foo bar abc '). +# +# Args: +# _flags_str_: string: string to search for in a list of strings +# unnamed: list: list of strings +# Returns: +# boolean: true if item is in the list +_flags_itemInList() { + _flags_str_=$1 + shift + + echo " ${*:-} " |grep " ${_flags_str_} " >/dev/null + if [ $? -eq 0 ]; then + flags_return=${FLAGS_TRUE} + else + flags_return=${FLAGS_FALSE} + fi + + unset _flags_str_ + return ${flags_return} +} + +# Returns the width of the current screen. +# +# Output: +# integer: width in columns of the current screen. +_flags_columns() +{ + if [ -z "${__flags_columns}" ]; then + # determine the value and store it + if eval stty size >/dev/null 2>&1; then + # stty size worked :-) + set -- `stty size` + __flags_columns=$2 + elif eval tput cols >/dev/null 2>&1; then + set -- `tput cols` + __flags_columns=$1 + else + __flags_columns=80 # default terminal width + fi + fi + echo ${__flags_columns} +} + +# Validate a boolean. +# +# Args: +# _flags__bool: boolean: value to validate +# Returns: +# bool: true if the value is a valid boolean +_flags_validateBoolean() +{ + _flags_bool_=$1 + + flags_return=${FLAGS_TRUE} + case "${_flags_bool_}" in + true|t|0) ;; + false|f|1) ;; + *) flags_return=${FLAGS_FALSE} ;; + esac + + unset _flags_bool_ + return ${flags_return} +} + +# Validate a float. +# +# Args: +# _flags__float: float: value to validate +# Returns: +# bool: true if the value is a valid float +_flags_validateFloat() +{ + _flags_float_=$1 + + if _flags_validateInteger ${_flags_float_}; then + flags_return=${FLAGS_TRUE} + else + flags_return=${FLAGS_TRUE} + case ${_flags_float_} in + -*) # negative floats + _flags_test_=`expr -- "${_flags_float_}" :\ + '\(-[0-9][0-9]*\.[0-9][0-9]*\)'` + ;; + *) # positive floats + _flags_test_=`expr -- "${_flags_float_}" :\ + '\([0-9][0-9]*\.[0-9][0-9]*\)'` + ;; + esac + [ "${_flags_test_}" != "${_flags_float_}" ] && flags_return=${FLAGS_FALSE} + fi + + unset _flags_float_ _flags_test_ + return ${flags_return} +} + +# Validate an integer. +# +# Args: +# _flags__integer: interger: value to validate +# Returns: +# bool: true if the value is a valid integer +_flags_validateInteger() +{ + _flags_int_=$1 + + flags_return=${FLAGS_TRUE} + case ${_flags_int_} in + -*) # negative ints + _flags_test_=`expr -- "${_flags_int_}" : '\(-[0-9][0-9]*\)'` + ;; + *) # positive ints + _flags_test_=`expr -- "${_flags_int_}" : '\([0-9][0-9]*\)'` + ;; + esac + [ "${_flags_test_}" != "${_flags_int_}" ] && flags_return=${FLAGS_FALSE} + + unset _flags_int_ _flags_test_ + return ${flags_return} +} + +# Parse command-line options using the standard getopt. +# +# Note: the flag options are passed around in the global __flags_opts so that +# the formatting is not lost due to shell parsing and such. +# +# Args: +# @: varies: command-line options to parse +# Returns: +# integer: a FLAGS success condition +_flags_getoptStandard() +{ + flags_return=${FLAGS_TRUE} + _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}` + + # check for spaces in passed options + for _flags_opt_ in "$@"; do + # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 + _flags_match_=`echo "x${_flags_opt_}x" |sed 's/ //g'` + if [ "${_flags_match_}" != "x${_flags_opt_}x" ]; then + flags_error='the available getopt does not support spaces in options' + flags_return=${FLAGS_ERROR} + break + fi + done + + if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then + __flags_opts=`getopt ${_flags_shortOpts_} $@ 2>&1` + _flags_rtrn_=$? + if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then + _flags_warn "${__flags_opts}" + flags_error='unable to parse provided options with getopt.' + flags_return=${FLAGS_ERROR} + fi + fi + + unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_ + return ${flags_return} +} + +# Parse command-line options using the enhanced getopt. +# +# Note: the flag options are passed around in the global __flags_opts so that +# the formatting is not lost due to shell parsing and such. +# +# Args: +# @: varies: command-line options to parse +# Returns: +# integer: a FLAGS success condition +_flags_getoptEnhanced() +{ + flags_return=${FLAGS_TRUE} + _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}` + _flags_boolOpts_=`echo "${__flags_boolNames}" \ + |sed 's/^ *//;s/ *$//;s/ /,/g'` + _flags_longOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}` + + __flags_opts=`${FLAGS_GETOPT_CMD} \ + -o ${_flags_shortOpts_} \ + -l "${_flags_longOpts_},${_flags_boolOpts_}" \ + -- "$@" 2>&1` + _flags_rtrn_=$? + if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then + _flags_warn "${__flags_opts}" + flags_error='unable to parse provided options with getopt.' + flags_return=${FLAGS_ERROR} + fi + + unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_ + return ${flags_return} +} + +# Dynamically parse a getopt result and set appropriate variables. +# +# This function does the actual conversion of getopt output and runs it through +# the standard case structure for parsing. The case structure is actually quite +# dynamic to support any number of flags. +# +# Args: +# argc: int: original command-line argument count +# @: varies: output from getopt parsing +# Returns: +# integer: a FLAGS success condition +_flags_parseGetopt() +{ + _flags_argc_=$1 + shift + + flags_return=${FLAGS_TRUE} + + if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then + set -- $@ + else + # note the quotes around the `$@' -- they are essential! + eval set -- "$@" + fi + + # provide user with number of arguments to shift by later + # NOTE: the FLAGS_ARGC variable is obsolete as of 1.0.3 because it does not + # properly give user access to non-flag arguments mixed in between flag + # arguments. Its usage was replaced by FLAGS_ARGV, and it is being kept only + # for backwards compatibility reasons. + FLAGS_ARGC=`expr $# - 1 - ${_flags_argc_}` + + # handle options. note options with values must do an additional shift + while true; do + _flags_opt_=$1 + _flags_arg_=${2:-} + _flags_type_=${__FLAGS_TYPE_NONE} + _flags_name_='' + + # determine long flag name + case "${_flags_opt_}" in + --) shift; break ;; # discontinue option parsing + + --*) # long option + _flags_opt_=`expr -- "${_flags_opt_}" : '--\(.*\)'` + _flags_len_=${__FLAGS_LEN_LONG} + if _flags_itemInList "${_flags_opt_}" ${__flags_longNames}; then + _flags_name_=${_flags_opt_} + else + # check for negated long boolean version + if _flags_itemInList "${_flags_opt_}" ${__flags_boolNames}; then + _flags_name_=`expr -- "${_flags_opt_}" : 'no\(.*\)'` + _flags_type_=${__FLAGS_TYPE_BOOLEAN} + _flags_arg_=${__FLAGS_NULL} + fi + fi + ;; + + -*) # short option + _flags_opt_=`expr -- "${_flags_opt_}" : '-\(.*\)'` + _flags_len_=${__FLAGS_LEN_SHORT} + if _flags_itemInList "${_flags_opt_}" ${__flags_shortNames}; then + # yes. match short name to long name. note purposeful off-by-one + # (too high) with awk calculations. + _flags_pos_=`echo "${__flags_shortNames}" \ + |awk 'BEGIN{RS=" ";rn=0}$0==e{rn=NR}END{print rn}' \ + e=${_flags_opt_}` + _flags_name_=`echo "${__flags_longNames}" \ + |awk 'BEGIN{RS=" "}rn==NR{print $0}' rn="${_flags_pos_}"` + fi + ;; + esac + + # die if the flag was unrecognized + if [ -z "${_flags_name_}" ]; then + flags_error="unrecognized option (${_flags_opt_})" + flags_return=${FLAGS_ERROR} + break + fi + + # set new flag value + _flags_usName_=`_flags_underscoreName ${_flags_name_}` + [ ${_flags_type_} -eq ${__FLAGS_TYPE_NONE} ] && \ + _flags_type_=`_flags_getFlagInfo \ + "${_flags_usName_}" ${__FLAGS_INFO_TYPE}` + case ${_flags_type_} in + ${__FLAGS_TYPE_BOOLEAN}) + if [ ${_flags_len_} -eq ${__FLAGS_LEN_LONG} ]; then + if [ "${_flags_arg_}" != "${__FLAGS_NULL}" ]; then + eval "FLAGS_${_flags_usName_}=${FLAGS_TRUE}" + else + eval "FLAGS_${_flags_usName_}=${FLAGS_FALSE}" + fi + else + _flags_strToEval_="_flags_val_=\ +\${__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}}" + eval "${_flags_strToEval_}" + if [ ${_flags_val_} -eq ${FLAGS_FALSE} ]; then + eval "FLAGS_${_flags_usName_}=${FLAGS_TRUE}" + else + eval "FLAGS_${_flags_usName_}=${FLAGS_FALSE}" + fi + fi + ;; + + ${__FLAGS_TYPE_FLOAT}) + if _flags_validateFloat "${_flags_arg_}"; then + eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" + else + flags_error="invalid float value (${_flags_arg_})" + flags_return=${FLAGS_ERROR} + break + fi + ;; + + ${__FLAGS_TYPE_INTEGER}) + if _flags_validateInteger "${_flags_arg_}"; then + eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" + else + flags_error="invalid integer value (${_flags_arg_})" + flags_return=${FLAGS_ERROR} + break + fi + ;; + + ${__FLAGS_TYPE_STRING}) + eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" + ;; + esac + + # handle special case help flag + if [ "${_flags_usName_}" = 'help' ]; then + if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then + flags_help + flags_error='help requested' + flags_return=${FLAGS_TRUE} + break + fi + fi + + # shift the option and non-boolean arguements out. + shift + [ ${_flags_type_} != ${__FLAGS_TYPE_BOOLEAN} ] && shift + done + + # give user back non-flag arguments + FLAGS_ARGV='' + while [ $# -gt 0 ]; do + FLAGS_ARGV="${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'" + shift + done + + unset _flags_arg_ _flags_len_ _flags_name_ _flags_opt_ _flags_pos_ \ + _flags_strToEval_ _flags_type_ _flags_usName_ _flags_val_ + return ${flags_return} +} + +#------------------------------------------------------------------------------ +# public functions +# + +# A basic boolean flag. Boolean flags do not take any arguments, and their +# value is either 1 (false) or 0 (true). For long flags, the false value is +# specified on the command line by prepending the word 'no'. With short flags, +# the presense of the flag toggles the current value between true and false. +# Specifying a short boolean flag twice on the command results in returning the +# value back to the default value. +# +# A default value is required for boolean flags. +# +# For example, lets say a Boolean flag was created whose long name was 'update' +# and whose short name was 'x', and the default value was 'false'. This flag +# could be explicitly set to 'true' with '--update' or by '-x', and it could be +# explicitly set to 'false' with '--noupdate'. +DEFINE_boolean() { _flags_define ${__FLAGS_TYPE_BOOLEAN} "$@"; } + +# Other basic flags. +DEFINE_float() { _flags_define ${__FLAGS_TYPE_FLOAT} "$@"; } +DEFINE_integer() { _flags_define ${__FLAGS_TYPE_INTEGER} "$@"; } +DEFINE_string() { _flags_define ${__FLAGS_TYPE_STRING} "$@"; } + +# Parse the flags. +# +# Args: +# unnamed: list: command-line flags to parse +# Returns: +# integer: success of operation, or error +FLAGS() +{ + # define a standard 'help' flag if one isn't already defined + [ -z "${__flags_help_type:-}" ] && \ + DEFINE_boolean 'help' false 'show this help' 'h' + + # parse options + if [ $# -gt 0 ]; then + if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then + _flags_getoptStandard "$@" + else + _flags_getoptEnhanced "$@" + fi + flags_return=$? + else + # nothing passed; won't bother running getopt + __flags_opts='--' + flags_return=${FLAGS_TRUE} + fi + + if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then + _flags_parseGetopt $# "${__flags_opts}" + flags_return=$? + fi + + [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_fatal "${flags_error}" + return ${flags_return} +} + +# This is a helper function for determining the 'getopt' version for platforms +# where the detection isn't working. It simply outputs debug information that +# can be included in a bug report. +# +# Args: +# none +# Output: +# debug info that can be included in a bug report +# Returns: +# nothing +flags_getoptInfo() +{ + # platform info + _flags_debug "uname -a: `uname -a`" + _flags_debug "PATH: ${PATH}" + + # shell info + if [ -n "${BASH_VERSION:-}" ]; then + _flags_debug 'shell: bash' + _flags_debug "BASH_VERSION: ${BASH_VERSION}" + elif [ -n "${ZSH_VERSION:-}" ]; then + _flags_debug 'shell: zsh' + _flags_debug "ZSH_VERSION: ${ZSH_VERSION}" + fi + + # getopt info + ${FLAGS_GETOPT_CMD} >/dev/null + _flags_getoptReturn=$? + _flags_debug "getopt return: ${_flags_getoptReturn}" + _flags_debug "getopt --version: `${FLAGS_GETOPT_CMD} --version 2>&1`" + + unset _flags_getoptReturn +} + +# Returns whether the detected getopt version is the enhanced version. +# +# Args: +# none +# Output: +# none +# Returns: +# bool: true if getopt is the enhanced version +flags_getoptIsEnh() +{ + test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} +} + +# Returns whether the detected getopt version is the standard version. +# +# Args: +# none +# Returns: +# bool: true if getopt is the standard version +flags_getoptIsStd() +{ + test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD} +} + +# This is effectively a 'usage()' function. It prints usage information and +# exits the program with ${FLAGS_FALSE} if it is ever found in the command line +# arguments. Note this function can be overridden so other apps can define +# their own --help flag, replacing this one, if they want. +# +# Args: +# none +# Returns: +# integer: success of operation (always returns true) +flags_help() +{ + if [ -n "${FLAGS_HELP:-}" ]; then + echo "${FLAGS_HELP}" >&2 + else + echo "USAGE: ${FLAGS_PARENT:-$0} [flags] args" >&2 + fi + if [ -n "${__flags_longNames}" ]; then + echo 'flags:' >&2 + for flags_name_ in ${__flags_longNames}; do + flags_flagStr_='' + flags_boolStr_='' + flags_usName_=`_flags_underscoreName ${flags_name_}` + + flags_default_=`_flags_getFlagInfo \ + "${flags_usName_}" ${__FLAGS_INFO_DEFAULT}` + flags_help_=`_flags_getFlagInfo \ + "${flags_usName_}" ${__FLAGS_INFO_HELP}` + flags_short_=`_flags_getFlagInfo \ + "${flags_usName_}" ${__FLAGS_INFO_SHORT}` + flags_type_=`_flags_getFlagInfo \ + "${flags_usName_}" ${__FLAGS_INFO_TYPE}` + + [ "${flags_short_}" != "${__FLAGS_NULL}" ] && \ + flags_flagStr_="-${flags_short_}" + + if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ]; then + [ "${flags_short_}" != "${__FLAGS_NULL}" ] && \ + flags_flagStr_="${flags_flagStr_}," + # add [no] to long boolean flag names, except the 'help' flag + [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} \ + -a "${flags_usName_}" != 'help' ] && \ + flags_boolStr_='[no]' + flags_flagStr_="${flags_flagStr_}--${flags_boolStr_}${flags_name_}:" + fi + + case ${flags_type_} in + ${__FLAGS_TYPE_BOOLEAN}) + if [ ${flags_default_} -eq ${FLAGS_TRUE} ]; then + flags_defaultStr_='true' + else + flags_defaultStr_='false' + fi + ;; + ${__FLAGS_TYPE_FLOAT}|${__FLAGS_TYPE_INTEGER}) + flags_defaultStr_=${flags_default_} ;; + ${__FLAGS_TYPE_STRING}) flags_defaultStr_="'${flags_default_}'" ;; + esac + flags_defaultStr_="(default: ${flags_defaultStr_})" + + flags_helpStr_=" ${flags_flagStr_} ${flags_help_} ${flags_defaultStr_}" + flags_helpStrLen_=`expr -- "${flags_helpStr_}" : '.*'` + flags_columns_=`_flags_columns` + if [ ${flags_helpStrLen_} -lt ${flags_columns_} ]; then + echo "${flags_helpStr_}" >&2 + else + echo " ${flags_flagStr_} ${flags_help_}" >&2 + # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 + # because it doesn't like empty strings when used in this manner. + flags_emptyStr_="`echo \"x${flags_flagStr_}x\" \ + |awk '{printf "%"length($0)-2"s", ""}'`" + flags_helpStr_=" ${flags_emptyStr_} ${flags_defaultStr_}" + flags_helpStrLen_=`expr -- "${flags_helpStr_}" : '.*'` + if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD} \ + -o ${flags_helpStrLen_} -lt ${flags_columns_} ]; then + # indented to match help string + echo "${flags_helpStr_}" >&2 + else + # indented four from left to allow for longer defaults as long flag + # names might be used too, making things too long + echo " ${flags_defaultStr_}" >&2 + fi + fi + done + fi + + unset flags_boolStr_ flags_default_ flags_defaultStr_ flags_emptyStr_ \ + flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \ + flags_columns_ flags_short_ flags_type_ flags_usName_ + return ${FLAGS_TRUE} +} + +# Reset shflags back to an uninitialized state. +# +# Args: +# none +# Returns: +# nothing +flags_reset() +{ + for flags_name_ in ${__flags_longNames}; do + flags_usName_=`_flags_underscoreName ${flags_name_}` + flags_strToEval_="unset FLAGS_${flags_usName_}" + for flags_type_ in \ + ${__FLAGS_INFO_DEFAULT} \ + ${__FLAGS_INFO_HELP} \ + ${__FLAGS_INFO_SHORT} \ + ${__FLAGS_INFO_TYPE} + do + flags_strToEval_=\ +"${flags_strToEval_} __flags_${flags_usName_}_${flags_type_}" + done + eval ${flags_strToEval_} + done + + # reset internal variables + __flags_boolNames=' ' + __flags_longNames=' ' + __flags_shortNames=' ' + __flags_definedNames=' ' + + unset flags_name_ flags_type_ flags_strToEval_ flags_usName_ +} diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_blas.h b/ChaosDataPlayer/GSL/include/gsl/gsl_blas.h new file mode 100644 index 0000000..7c42714 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_blas.h @@ -0,0 +1,602 @@ +/* blas/gsl_blas.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Author: G. Jungman + */ +#ifndef __GSL_BLAS_H__ +#define __GSL_BLAS_H__ + +#include +#include + +#include + + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* ======================================================================== + * Level 1 + * ======================================================================== + */ + +int gsl_blas_sdsdot (float alpha, + const gsl_vector_float * X, + const gsl_vector_float * Y, + float * result + ); + +int gsl_blas_dsdot (const gsl_vector_float * X, + const gsl_vector_float * Y, + double * result + ); + +int gsl_blas_sdot (const gsl_vector_float * X, + const gsl_vector_float * Y, + float * result + ); + +int gsl_blas_ddot (const gsl_vector * X, + const gsl_vector * Y, + double * result + ); + + +int gsl_blas_cdotu (const gsl_vector_complex_float * X, + const gsl_vector_complex_float * Y, + gsl_complex_float * dotu); + +int gsl_blas_cdotc (const gsl_vector_complex_float * X, + const gsl_vector_complex_float * Y, + gsl_complex_float * dotc); + +int gsl_blas_zdotu (const gsl_vector_complex * X, + const gsl_vector_complex * Y, + gsl_complex * dotu); + +int gsl_blas_zdotc (const gsl_vector_complex * X, + const gsl_vector_complex * Y, + gsl_complex * dotc); + + +float gsl_blas_snrm2 (const gsl_vector_float * X); +float gsl_blas_sasum (const gsl_vector_float * X); +double gsl_blas_dnrm2 (const gsl_vector * X); +double gsl_blas_dasum (const gsl_vector * X); +float gsl_blas_scnrm2 (const gsl_vector_complex_float * X); +float gsl_blas_scasum (const gsl_vector_complex_float * X); +double gsl_blas_dznrm2 (const gsl_vector_complex * X); +double gsl_blas_dzasum (const gsl_vector_complex * X); + + +CBLAS_INDEX_t gsl_blas_isamax (const gsl_vector_float * X); +CBLAS_INDEX_t gsl_blas_idamax (const gsl_vector * X); +CBLAS_INDEX_t gsl_blas_icamax (const gsl_vector_complex_float * X); +CBLAS_INDEX_t gsl_blas_izamax (const gsl_vector_complex * X); + + +int gsl_blas_sswap (gsl_vector_float * X, + gsl_vector_float * Y); + +int gsl_blas_scopy (const gsl_vector_float * X, + gsl_vector_float * Y); + +int gsl_blas_saxpy (float alpha, + const gsl_vector_float * X, + gsl_vector_float * Y); + +int gsl_blas_dswap (gsl_vector * X, + gsl_vector * Y); + +int gsl_blas_dcopy (const gsl_vector * X, + gsl_vector * Y); + +int gsl_blas_daxpy (double alpha, + const gsl_vector * X, + gsl_vector * Y); + +int gsl_blas_cswap (gsl_vector_complex_float * X, + gsl_vector_complex_float * Y); + +int gsl_blas_ccopy (const gsl_vector_complex_float * X, + gsl_vector_complex_float * Y); + +int gsl_blas_caxpy (const gsl_complex_float alpha, + const gsl_vector_complex_float * X, + gsl_vector_complex_float * Y); + +int gsl_blas_zswap (gsl_vector_complex * X, + gsl_vector_complex * Y); + +int gsl_blas_zcopy (const gsl_vector_complex * X, + gsl_vector_complex * Y); + +int gsl_blas_zaxpy (const gsl_complex alpha, + const gsl_vector_complex * X, + gsl_vector_complex * Y); + + +int gsl_blas_srotg (float a[], float b[], float c[], float s[]); + +int gsl_blas_srotmg (float d1[], float d2[], float b1[], float b2, float P[]); + +int gsl_blas_srot (gsl_vector_float * X, + gsl_vector_float * Y, + float c, float s); + +int gsl_blas_srotm (gsl_vector_float * X, + gsl_vector_float * Y, + const float P[]); + +int gsl_blas_drotg (double a[], double b[], double c[], double s[]); + +int gsl_blas_drotmg (double d1[], double d2[], double b1[], + double b2, double P[]); + +int gsl_blas_drot (gsl_vector * X, + gsl_vector * Y, + const double c, const double s); + +int gsl_blas_drotm (gsl_vector * X, + gsl_vector * Y, + const double P[]); + + +void gsl_blas_sscal (float alpha, gsl_vector_float * X); +void gsl_blas_dscal (double alpha, gsl_vector * X); +void gsl_blas_cscal (const gsl_complex_float alpha, gsl_vector_complex_float * X); +void gsl_blas_zscal (const gsl_complex alpha, gsl_vector_complex * X); +void gsl_blas_csscal (float alpha, gsl_vector_complex_float * X); +void gsl_blas_zdscal (double alpha, gsl_vector_complex * X); + + +/* =========================================================================== + * Level 2 + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +int gsl_blas_sgemv (CBLAS_TRANSPOSE_t TransA, + float alpha, + const gsl_matrix_float * A, + const gsl_vector_float * X, + float beta, + gsl_vector_float * Y); + +int gsl_blas_strmv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_float * A, + gsl_vector_float * X); + +int gsl_blas_strsv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_float * A, + gsl_vector_float * X); + +int gsl_blas_dgemv (CBLAS_TRANSPOSE_t TransA, + double alpha, + const gsl_matrix * A, + const gsl_vector * X, + double beta, + gsl_vector * Y); + +int gsl_blas_dtrmv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix * A, + gsl_vector * X); + +int gsl_blas_dtrsv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix * A, + gsl_vector * X); + +int gsl_blas_cgemv (CBLAS_TRANSPOSE_t TransA, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_vector_complex_float * X, + const gsl_complex_float beta, + gsl_vector_complex_float * Y); + +int gsl_blas_ctrmv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_complex_float * A, + gsl_vector_complex_float * X); + +int gsl_blas_ctrsv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_complex_float * A, + gsl_vector_complex_float * X); + +int gsl_blas_zgemv (CBLAS_TRANSPOSE_t TransA, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_vector_complex * X, + const gsl_complex beta, + gsl_vector_complex * Y); + +int gsl_blas_ztrmv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_complex * A, + gsl_vector_complex * X); + +int gsl_blas_ztrsv (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t TransA, CBLAS_DIAG_t Diag, + const gsl_matrix_complex * A, + gsl_vector_complex *X); + +/* + * Routines with S and D prefixes only + */ +int gsl_blas_ssymv (CBLAS_UPLO_t Uplo, + float alpha, + const gsl_matrix_float * A, + const gsl_vector_float * X, + float beta, + gsl_vector_float * Y); + +int gsl_blas_sger (float alpha, + const gsl_vector_float * X, + const gsl_vector_float * Y, + gsl_matrix_float * A); + +int gsl_blas_ssyr (CBLAS_UPLO_t Uplo, + float alpha, + const gsl_vector_float * X, + gsl_matrix_float * A); + +int gsl_blas_ssyr2 (CBLAS_UPLO_t Uplo, + float alpha, + const gsl_vector_float * X, + const gsl_vector_float * Y, + gsl_matrix_float * A); + +int gsl_blas_dsymv (CBLAS_UPLO_t Uplo, + double alpha, + const gsl_matrix * A, + const gsl_vector * X, + double beta, + gsl_vector * Y); +int gsl_blas_dger (double alpha, + const gsl_vector * X, + const gsl_vector * Y, + gsl_matrix * A); + +int gsl_blas_dsyr (CBLAS_UPLO_t Uplo, + double alpha, + const gsl_vector * X, + gsl_matrix * A); + +int gsl_blas_dsyr2 (CBLAS_UPLO_t Uplo, + double alpha, + const gsl_vector * X, + const gsl_vector * Y, + gsl_matrix * A); + +/* + * Routines with C and Z prefixes only + */ + +int gsl_blas_chemv (CBLAS_UPLO_t Uplo, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_vector_complex_float * X, + const gsl_complex_float beta, + gsl_vector_complex_float * Y); + +int gsl_blas_cgeru (const gsl_complex_float alpha, + const gsl_vector_complex_float * X, + const gsl_vector_complex_float * Y, + gsl_matrix_complex_float * A); + +int gsl_blas_cgerc (const gsl_complex_float alpha, + const gsl_vector_complex_float * X, + const gsl_vector_complex_float * Y, + gsl_matrix_complex_float * A); + +int gsl_blas_cher (CBLAS_UPLO_t Uplo, + float alpha, + const gsl_vector_complex_float * X, + gsl_matrix_complex_float * A); + +int gsl_blas_cher2 (CBLAS_UPLO_t Uplo, + const gsl_complex_float alpha, + const gsl_vector_complex_float * X, + const gsl_vector_complex_float * Y, + gsl_matrix_complex_float * A); + +int gsl_blas_zhemv (CBLAS_UPLO_t Uplo, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_vector_complex * X, + const gsl_complex beta, + gsl_vector_complex * Y); + +int gsl_blas_zgeru (const gsl_complex alpha, + const gsl_vector_complex * X, + const gsl_vector_complex * Y, + gsl_matrix_complex * A); + +int gsl_blas_zgerc (const gsl_complex alpha, + const gsl_vector_complex * X, + const gsl_vector_complex * Y, + gsl_matrix_complex * A); + +int gsl_blas_zher (CBLAS_UPLO_t Uplo, + double alpha, + const gsl_vector_complex * X, + gsl_matrix_complex * A); + +int gsl_blas_zher2 (CBLAS_UPLO_t Uplo, + const gsl_complex alpha, + const gsl_vector_complex * X, + const gsl_vector_complex * Y, + gsl_matrix_complex * A); + +/* + * =========================================================================== + * Prototypes for level 3 BLAS + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +int gsl_blas_sgemm (CBLAS_TRANSPOSE_t TransA, + CBLAS_TRANSPOSE_t TransB, + float alpha, + const gsl_matrix_float * A, + const gsl_matrix_float * B, + float beta, + gsl_matrix_float * C); + +int gsl_blas_ssymm (CBLAS_SIDE_t Side, CBLAS_UPLO_t Uplo, + float alpha, + const gsl_matrix_float * A, + const gsl_matrix_float * B, + float beta, + gsl_matrix_float * C); + +int gsl_blas_ssyrk (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, + float alpha, + const gsl_matrix_float * A, + float beta, + gsl_matrix_float * C); + +int gsl_blas_ssyr2k (CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t Trans, + float alpha, + const gsl_matrix_float * A, + const gsl_matrix_float * B, + float beta, + gsl_matrix_float * C); + +int gsl_blas_strmm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + float alpha, + const gsl_matrix_float * A, + gsl_matrix_float * B); + +int gsl_blas_strsm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + float alpha, + const gsl_matrix_float * A, + gsl_matrix_float * B); + +int gsl_blas_dgemm (CBLAS_TRANSPOSE_t TransA, + CBLAS_TRANSPOSE_t TransB, + double alpha, + const gsl_matrix * A, + const gsl_matrix * B, + double beta, + gsl_matrix * C); + +int gsl_blas_dsymm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, + double alpha, + const gsl_matrix * A, + const gsl_matrix * B, + double beta, + gsl_matrix * C); + +int gsl_blas_dsyrk (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + double alpha, + const gsl_matrix * A, + double beta, + gsl_matrix * C); + +int gsl_blas_dsyr2k (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + double alpha, + const gsl_matrix * A, + const gsl_matrix * B, + double beta, + gsl_matrix * C); + +int gsl_blas_dtrmm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + double alpha, + const gsl_matrix * A, + gsl_matrix * B); + +int gsl_blas_dtrsm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + double alpha, + const gsl_matrix * A, + gsl_matrix * B); + +int gsl_blas_cgemm (CBLAS_TRANSPOSE_t TransA, + CBLAS_TRANSPOSE_t TransB, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_matrix_complex_float * B, + const gsl_complex_float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_csymm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_matrix_complex_float * B, + const gsl_complex_float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_csyrk (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_complex_float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_csyr2k (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_matrix_complex_float * B, + const gsl_complex_float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_ctrmm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + gsl_matrix_complex_float * B); + +int gsl_blas_ctrsm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + gsl_matrix_complex_float * B); + +int gsl_blas_zgemm (CBLAS_TRANSPOSE_t TransA, + CBLAS_TRANSPOSE_t TransB, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_matrix_complex * B, + const gsl_complex beta, + gsl_matrix_complex * C); + +int gsl_blas_zsymm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_matrix_complex * B, + const gsl_complex beta, + gsl_matrix_complex * C); + +int gsl_blas_zsyrk (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_complex beta, + gsl_matrix_complex * C); + +int gsl_blas_zsyr2k (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_matrix_complex * B, + const gsl_complex beta, + gsl_matrix_complex *C); + +int gsl_blas_ztrmm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + const gsl_complex alpha, + const gsl_matrix_complex * A, + gsl_matrix_complex * B); + +int gsl_blas_ztrsm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, CBLAS_TRANSPOSE_t TransA, + CBLAS_DIAG_t Diag, + const gsl_complex alpha, + const gsl_matrix_complex * A, + gsl_matrix_complex * B); + +/* + * Routines with prefixes C and Z only + */ +int gsl_blas_chemm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_matrix_complex_float * B, + const gsl_complex_float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_cherk (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + float alpha, + const gsl_matrix_complex_float * A, + float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_cher2k (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex_float alpha, + const gsl_matrix_complex_float * A, + const gsl_matrix_complex_float * B, + float beta, + gsl_matrix_complex_float * C); + +int gsl_blas_zhemm (CBLAS_SIDE_t Side, + CBLAS_UPLO_t Uplo, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_matrix_complex * B, + const gsl_complex beta, + gsl_matrix_complex * C); + +int gsl_blas_zherk (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + double alpha, + const gsl_matrix_complex * A, + double beta, + gsl_matrix_complex * C); + +int gsl_blas_zher2k (CBLAS_UPLO_t Uplo, + CBLAS_TRANSPOSE_t Trans, + const gsl_complex alpha, + const gsl_matrix_complex * A, + const gsl_matrix_complex * B, + double beta, + gsl_matrix_complex * C); + + +__END_DECLS + +#endif /* __GSL_BLAS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_blas_types.h b/ChaosDataPlayer/GSL/include/gsl/gsl_blas_types.h new file mode 100644 index 0000000..923edb3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_blas_types.h @@ -0,0 +1,54 @@ +/* blas/gsl_blas_types.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Author: G. Jungman + */ +/* Based on draft BLAST C interface specification [Jul 7 1998] + */ +#ifndef __GSL_BLAS_TYPES_H__ +#define __GSL_BLAS_TYPES_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef CBLAS_INDEX CBLAS_INDEX_t; +typedef enum CBLAS_ORDER CBLAS_ORDER_t; +typedef enum CBLAS_TRANSPOSE CBLAS_TRANSPOSE_t; +typedef enum CBLAS_UPLO CBLAS_UPLO_t; +typedef enum CBLAS_DIAG CBLAS_DIAG_t; +typedef enum CBLAS_SIDE CBLAS_SIDE_t; + +/* typedef gsl_complex COMPLEX; */ + +__END_DECLS + + +#endif /* __GSL_BLAS_TYPES_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block.h new file mode 100644 index 0000000..f1f9ef8 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block.h @@ -0,0 +1,24 @@ +#ifndef __GSL_BLOCK_H__ +#define __GSL_BLOCK_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_BLOCK_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_char.h new file mode 100644 index 0000000..70bf969 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_char.h @@ -0,0 +1,65 @@ +/* block/gsl_block_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_CHAR_H__ +#define __GSL_BLOCK_CHAR_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_char_struct +{ + size_t size; + char *data; +}; + +typedef struct gsl_block_char_struct gsl_block_char; + +gsl_block_char *gsl_block_char_alloc (const size_t n); +gsl_block_char *gsl_block_char_calloc (const size_t n); +void gsl_block_char_free (gsl_block_char * b); + +int gsl_block_char_fread (FILE * stream, gsl_block_char * b); +int gsl_block_char_fwrite (FILE * stream, const gsl_block_char * b); +int gsl_block_char_fscanf (FILE * stream, gsl_block_char * b); +int gsl_block_char_fprintf (FILE * stream, const gsl_block_char * b, const char *format); + +int gsl_block_char_raw_fread (FILE * stream, char * b, const size_t n, const size_t stride); +int gsl_block_char_raw_fwrite (FILE * stream, const char * b, const size_t n, const size_t stride); +int gsl_block_char_raw_fscanf (FILE * stream, char * b, const size_t n, const size_t stride); +int gsl_block_char_raw_fprintf (FILE * stream, const char * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_char_size (const gsl_block_char * b); +char * gsl_block_char_data (const gsl_block_char * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_double.h new file mode 100644 index 0000000..bcf66c0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_double.h @@ -0,0 +1,65 @@ +/* block/gsl_block_complex_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_COMPLEX_DOUBLE_H__ +#define __GSL_BLOCK_COMPLEX_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_complex_struct +{ + size_t size; + double *data; +}; + +typedef struct gsl_block_complex_struct gsl_block_complex; + +gsl_block_complex *gsl_block_complex_alloc (const size_t n); +gsl_block_complex *gsl_block_complex_calloc (const size_t n); +void gsl_block_complex_free (gsl_block_complex * b); + +int gsl_block_complex_fread (FILE * stream, gsl_block_complex * b); +int gsl_block_complex_fwrite (FILE * stream, const gsl_block_complex * b); +int gsl_block_complex_fscanf (FILE * stream, gsl_block_complex * b); +int gsl_block_complex_fprintf (FILE * stream, const gsl_block_complex * b, const char *format); + +int gsl_block_complex_raw_fread (FILE * stream, double * b, const size_t n, const size_t stride); +int gsl_block_complex_raw_fwrite (FILE * stream, const double * b, const size_t n, const size_t stride); +int gsl_block_complex_raw_fscanf (FILE * stream, double * b, const size_t n, const size_t stride); +int gsl_block_complex_raw_fprintf (FILE * stream, const double * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_complex_size (const gsl_block_complex * b); +double * gsl_block_complex_data (const gsl_block_complex * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_float.h new file mode 100644 index 0000000..03595dc --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_float.h @@ -0,0 +1,65 @@ +/* block/gsl_block_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_COMPLEX_FLOAT_H__ +#define __GSL_BLOCK_COMPLEX_FLOAT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_complex_float_struct +{ + size_t size; + float *data; +}; + +typedef struct gsl_block_complex_float_struct gsl_block_complex_float; + +gsl_block_complex_float *gsl_block_complex_float_alloc (const size_t n); +gsl_block_complex_float *gsl_block_complex_float_calloc (const size_t n); +void gsl_block_complex_float_free (gsl_block_complex_float * b); + +int gsl_block_complex_float_fread (FILE * stream, gsl_block_complex_float * b); +int gsl_block_complex_float_fwrite (FILE * stream, const gsl_block_complex_float * b); +int gsl_block_complex_float_fscanf (FILE * stream, gsl_block_complex_float * b); +int gsl_block_complex_float_fprintf (FILE * stream, const gsl_block_complex_float * b, const char *format); + +int gsl_block_complex_float_raw_fread (FILE * stream, float * b, const size_t n, const size_t stride); +int gsl_block_complex_float_raw_fwrite (FILE * stream, const float * b, const size_t n, const size_t stride); +int gsl_block_complex_float_raw_fscanf (FILE * stream, float * b, const size_t n, const size_t stride); +int gsl_block_complex_float_raw_fprintf (FILE * stream, const float * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_complex_float_size (const gsl_block_complex_float * b); +float * gsl_block_complex_float_data (const gsl_block_complex_float * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_long_double.h new file mode 100644 index 0000000..eb0c605 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_complex_long_double.h @@ -0,0 +1,65 @@ +/* block/gsl_block_complex_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_complex_long_double_struct +{ + size_t size; + long double *data; +}; + +typedef struct gsl_block_complex_long_double_struct gsl_block_complex_long_double; + +gsl_block_complex_long_double *gsl_block_complex_long_double_alloc (const size_t n); +gsl_block_complex_long_double *gsl_block_complex_long_double_calloc (const size_t n); +void gsl_block_complex_long_double_free (gsl_block_complex_long_double * b); + +int gsl_block_complex_long_double_fread (FILE * stream, gsl_block_complex_long_double * b); +int gsl_block_complex_long_double_fwrite (FILE * stream, const gsl_block_complex_long_double * b); +int gsl_block_complex_long_double_fscanf (FILE * stream, gsl_block_complex_long_double * b); +int gsl_block_complex_long_double_fprintf (FILE * stream, const gsl_block_complex_long_double * b, const char *format); + +int gsl_block_complex_long_double_raw_fread (FILE * stream, long double * b, const size_t n, const size_t stride); +int gsl_block_complex_long_double_raw_fwrite (FILE * stream, const long double * b, const size_t n, const size_t stride); +int gsl_block_complex_long_double_raw_fscanf (FILE * stream, long double * b, const size_t n, const size_t stride); +int gsl_block_complex_long_double_raw_fprintf (FILE * stream, const long double * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_complex_long_double_size (const gsl_block_complex_long_double * b); +long double * gsl_block_complex_long_double_data (const gsl_block_complex_long_double * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_double.h new file mode 100644 index 0000000..3a95f4d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_double.h @@ -0,0 +1,65 @@ +/* block/gsl_block_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_DOUBLE_H__ +#define __GSL_BLOCK_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_struct +{ + size_t size; + double *data; +}; + +typedef struct gsl_block_struct gsl_block; + +gsl_block *gsl_block_alloc (const size_t n); +gsl_block *gsl_block_calloc (const size_t n); +void gsl_block_free (gsl_block * b); + +int gsl_block_fread (FILE * stream, gsl_block * b); +int gsl_block_fwrite (FILE * stream, const gsl_block * b); +int gsl_block_fscanf (FILE * stream, gsl_block * b); +int gsl_block_fprintf (FILE * stream, const gsl_block * b, const char *format); + +int gsl_block_raw_fread (FILE * stream, double * b, const size_t n, const size_t stride); +int gsl_block_raw_fwrite (FILE * stream, const double * b, const size_t n, const size_t stride); +int gsl_block_raw_fscanf (FILE * stream, double * b, const size_t n, const size_t stride); +int gsl_block_raw_fprintf (FILE * stream, const double * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_size (const gsl_block * b); +double * gsl_block_data (const gsl_block * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_float.h new file mode 100644 index 0000000..f1c3fb3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_float.h @@ -0,0 +1,65 @@ +/* block/gsl_block_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_FLOAT_H__ +#define __GSL_BLOCK_FLOAT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_float_struct +{ + size_t size; + float *data; +}; + +typedef struct gsl_block_float_struct gsl_block_float; + +gsl_block_float *gsl_block_float_alloc (const size_t n); +gsl_block_float *gsl_block_float_calloc (const size_t n); +void gsl_block_float_free (gsl_block_float * b); + +int gsl_block_float_fread (FILE * stream, gsl_block_float * b); +int gsl_block_float_fwrite (FILE * stream, const gsl_block_float * b); +int gsl_block_float_fscanf (FILE * stream, gsl_block_float * b); +int gsl_block_float_fprintf (FILE * stream, const gsl_block_float * b, const char *format); + +int gsl_block_float_raw_fread (FILE * stream, float * b, const size_t n, const size_t stride); +int gsl_block_float_raw_fwrite (FILE * stream, const float * b, const size_t n, const size_t stride); +int gsl_block_float_raw_fscanf (FILE * stream, float * b, const size_t n, const size_t stride); +int gsl_block_float_raw_fprintf (FILE * stream, const float * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_float_size (const gsl_block_float * b); +float * gsl_block_float_data (const gsl_block_float * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_int.h new file mode 100644 index 0000000..2213f47 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_int.h @@ -0,0 +1,65 @@ +/* block/gsl_block_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_INT_H__ +#define __GSL_BLOCK_INT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_int_struct +{ + size_t size; + int *data; +}; + +typedef struct gsl_block_int_struct gsl_block_int; + +gsl_block_int *gsl_block_int_alloc (const size_t n); +gsl_block_int *gsl_block_int_calloc (const size_t n); +void gsl_block_int_free (gsl_block_int * b); + +int gsl_block_int_fread (FILE * stream, gsl_block_int * b); +int gsl_block_int_fwrite (FILE * stream, const gsl_block_int * b); +int gsl_block_int_fscanf (FILE * stream, gsl_block_int * b); +int gsl_block_int_fprintf (FILE * stream, const gsl_block_int * b, const char *format); + +int gsl_block_int_raw_fread (FILE * stream, int * b, const size_t n, const size_t stride); +int gsl_block_int_raw_fwrite (FILE * stream, const int * b, const size_t n, const size_t stride); +int gsl_block_int_raw_fscanf (FILE * stream, int * b, const size_t n, const size_t stride); +int gsl_block_int_raw_fprintf (FILE * stream, const int * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_int_size (const gsl_block_int * b); +int * gsl_block_int_data (const gsl_block_int * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_long.h new file mode 100644 index 0000000..0c30aa5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_long.h @@ -0,0 +1,65 @@ +/* block/gsl_block_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_LONG_H__ +#define __GSL_BLOCK_LONG_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_long_struct +{ + size_t size; + long *data; +}; + +typedef struct gsl_block_long_struct gsl_block_long; + +gsl_block_long *gsl_block_long_alloc (const size_t n); +gsl_block_long *gsl_block_long_calloc (const size_t n); +void gsl_block_long_free (gsl_block_long * b); + +int gsl_block_long_fread (FILE * stream, gsl_block_long * b); +int gsl_block_long_fwrite (FILE * stream, const gsl_block_long * b); +int gsl_block_long_fscanf (FILE * stream, gsl_block_long * b); +int gsl_block_long_fprintf (FILE * stream, const gsl_block_long * b, const char *format); + +int gsl_block_long_raw_fread (FILE * stream, long * b, const size_t n, const size_t stride); +int gsl_block_long_raw_fwrite (FILE * stream, const long * b, const size_t n, const size_t stride); +int gsl_block_long_raw_fscanf (FILE * stream, long * b, const size_t n, const size_t stride); +int gsl_block_long_raw_fprintf (FILE * stream, const long * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_long_size (const gsl_block_long * b); +long * gsl_block_long_data (const gsl_block_long * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_long_double.h new file mode 100644 index 0000000..639cd81 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_long_double.h @@ -0,0 +1,65 @@ +/* block/gsl_block_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_LONG_DOUBLE_H__ +#define __GSL_BLOCK_LONG_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_long_double_struct +{ + size_t size; + long double *data; +}; + +typedef struct gsl_block_long_double_struct gsl_block_long_double; + +gsl_block_long_double *gsl_block_long_double_alloc (const size_t n); +gsl_block_long_double *gsl_block_long_double_calloc (const size_t n); +void gsl_block_long_double_free (gsl_block_long_double * b); + +int gsl_block_long_double_fread (FILE * stream, gsl_block_long_double * b); +int gsl_block_long_double_fwrite (FILE * stream, const gsl_block_long_double * b); +int gsl_block_long_double_fscanf (FILE * stream, gsl_block_long_double * b); +int gsl_block_long_double_fprintf (FILE * stream, const gsl_block_long_double * b, const char *format); + +int gsl_block_long_double_raw_fread (FILE * stream, long double * b, const size_t n, const size_t stride); +int gsl_block_long_double_raw_fwrite (FILE * stream, const long double * b, const size_t n, const size_t stride); +int gsl_block_long_double_raw_fscanf (FILE * stream, long double * b, const size_t n, const size_t stride); +int gsl_block_long_double_raw_fprintf (FILE * stream, const long double * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_long_double_size (const gsl_block_long_double * b); +long double * gsl_block_long_double_data (const gsl_block_long_double * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_short.h new file mode 100644 index 0000000..9744775 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_short.h @@ -0,0 +1,65 @@ +/* block/gsl_block_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_SHORT_H__ +#define __GSL_BLOCK_SHORT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_short_struct +{ + size_t size; + short *data; +}; + +typedef struct gsl_block_short_struct gsl_block_short; + +gsl_block_short *gsl_block_short_alloc (const size_t n); +gsl_block_short *gsl_block_short_calloc (const size_t n); +void gsl_block_short_free (gsl_block_short * b); + +int gsl_block_short_fread (FILE * stream, gsl_block_short * b); +int gsl_block_short_fwrite (FILE * stream, const gsl_block_short * b); +int gsl_block_short_fscanf (FILE * stream, gsl_block_short * b); +int gsl_block_short_fprintf (FILE * stream, const gsl_block_short * b, const char *format); + +int gsl_block_short_raw_fread (FILE * stream, short * b, const size_t n, const size_t stride); +int gsl_block_short_raw_fwrite (FILE * stream, const short * b, const size_t n, const size_t stride); +int gsl_block_short_raw_fscanf (FILE * stream, short * b, const size_t n, const size_t stride); +int gsl_block_short_raw_fprintf (FILE * stream, const short * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_short_size (const gsl_block_short * b); +short * gsl_block_short_data (const gsl_block_short * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_uchar.h new file mode 100644 index 0000000..58cf789 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_uchar.h @@ -0,0 +1,65 @@ +/* block/gsl_block_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_UCHAR_H__ +#define __GSL_BLOCK_UCHAR_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_uchar_struct +{ + size_t size; + unsigned char *data; +}; + +typedef struct gsl_block_uchar_struct gsl_block_uchar; + +gsl_block_uchar *gsl_block_uchar_alloc (const size_t n); +gsl_block_uchar *gsl_block_uchar_calloc (const size_t n); +void gsl_block_uchar_free (gsl_block_uchar * b); + +int gsl_block_uchar_fread (FILE * stream, gsl_block_uchar * b); +int gsl_block_uchar_fwrite (FILE * stream, const gsl_block_uchar * b); +int gsl_block_uchar_fscanf (FILE * stream, gsl_block_uchar * b); +int gsl_block_uchar_fprintf (FILE * stream, const gsl_block_uchar * b, const char *format); + +int gsl_block_uchar_raw_fread (FILE * stream, unsigned char * b, const size_t n, const size_t stride); +int gsl_block_uchar_raw_fwrite (FILE * stream, const unsigned char * b, const size_t n, const size_t stride); +int gsl_block_uchar_raw_fscanf (FILE * stream, unsigned char * b, const size_t n, const size_t stride); +int gsl_block_uchar_raw_fprintf (FILE * stream, const unsigned char * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_uchar_size (const gsl_block_uchar * b); +unsigned char * gsl_block_uchar_data (const gsl_block_uchar * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_uint.h new file mode 100644 index 0000000..52cf2cb --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_uint.h @@ -0,0 +1,65 @@ +/* block/gsl_block_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_UINT_H__ +#define __GSL_BLOCK_UINT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_uint_struct +{ + size_t size; + unsigned int *data; +}; + +typedef struct gsl_block_uint_struct gsl_block_uint; + +gsl_block_uint *gsl_block_uint_alloc (const size_t n); +gsl_block_uint *gsl_block_uint_calloc (const size_t n); +void gsl_block_uint_free (gsl_block_uint * b); + +int gsl_block_uint_fread (FILE * stream, gsl_block_uint * b); +int gsl_block_uint_fwrite (FILE * stream, const gsl_block_uint * b); +int gsl_block_uint_fscanf (FILE * stream, gsl_block_uint * b); +int gsl_block_uint_fprintf (FILE * stream, const gsl_block_uint * b, const char *format); + +int gsl_block_uint_raw_fread (FILE * stream, unsigned int * b, const size_t n, const size_t stride); +int gsl_block_uint_raw_fwrite (FILE * stream, const unsigned int * b, const size_t n, const size_t stride); +int gsl_block_uint_raw_fscanf (FILE * stream, unsigned int * b, const size_t n, const size_t stride); +int gsl_block_uint_raw_fprintf (FILE * stream, const unsigned int * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_uint_size (const gsl_block_uint * b); +unsigned int * gsl_block_uint_data (const gsl_block_uint * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_ulong.h new file mode 100644 index 0000000..863ff47 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_ulong.h @@ -0,0 +1,65 @@ +/* block/gsl_block_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_ULONG_H__ +#define __GSL_BLOCK_ULONG_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_ulong_struct +{ + size_t size; + unsigned long *data; +}; + +typedef struct gsl_block_ulong_struct gsl_block_ulong; + +gsl_block_ulong *gsl_block_ulong_alloc (const size_t n); +gsl_block_ulong *gsl_block_ulong_calloc (const size_t n); +void gsl_block_ulong_free (gsl_block_ulong * b); + +int gsl_block_ulong_fread (FILE * stream, gsl_block_ulong * b); +int gsl_block_ulong_fwrite (FILE * stream, const gsl_block_ulong * b); +int gsl_block_ulong_fscanf (FILE * stream, gsl_block_ulong * b); +int gsl_block_ulong_fprintf (FILE * stream, const gsl_block_ulong * b, const char *format); + +int gsl_block_ulong_raw_fread (FILE * stream, unsigned long * b, const size_t n, const size_t stride); +int gsl_block_ulong_raw_fwrite (FILE * stream, const unsigned long * b, const size_t n, const size_t stride); +int gsl_block_ulong_raw_fscanf (FILE * stream, unsigned long * b, const size_t n, const size_t stride); +int gsl_block_ulong_raw_fprintf (FILE * stream, const unsigned long * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_ulong_size (const gsl_block_ulong * b); +unsigned long * gsl_block_ulong_data (const gsl_block_ulong * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_block_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_block_ushort.h new file mode 100644 index 0000000..24ad7db --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_block_ushort.h @@ -0,0 +1,65 @@ +/* block/gsl_block_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BLOCK_USHORT_H__ +#define __GSL_BLOCK_USHORT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_block_ushort_struct +{ + size_t size; + unsigned short *data; +}; + +typedef struct gsl_block_ushort_struct gsl_block_ushort; + +gsl_block_ushort *gsl_block_ushort_alloc (const size_t n); +gsl_block_ushort *gsl_block_ushort_calloc (const size_t n); +void gsl_block_ushort_free (gsl_block_ushort * b); + +int gsl_block_ushort_fread (FILE * stream, gsl_block_ushort * b); +int gsl_block_ushort_fwrite (FILE * stream, const gsl_block_ushort * b); +int gsl_block_ushort_fscanf (FILE * stream, gsl_block_ushort * b); +int gsl_block_ushort_fprintf (FILE * stream, const gsl_block_ushort * b, const char *format); + +int gsl_block_ushort_raw_fread (FILE * stream, unsigned short * b, const size_t n, const size_t stride); +int gsl_block_ushort_raw_fwrite (FILE * stream, const unsigned short * b, const size_t n, const size_t stride); +int gsl_block_ushort_raw_fscanf (FILE * stream, unsigned short * b, const size_t n, const size_t stride); +int gsl_block_ushort_raw_fprintf (FILE * stream, const unsigned short * b, const size_t n, const size_t stride, const char *format); + +size_t gsl_block_ushort_size (const gsl_block_ushort * b); +unsigned short * gsl_block_ushort_data (const gsl_block_ushort * b); + +__END_DECLS + +#endif /* __GSL_BLOCK_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_bspline.h b/ChaosDataPlayer/GSL/include/gsl/gsl_bspline.h new file mode 100644 index 0000000..878fe49 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_bspline.h @@ -0,0 +1,108 @@ +/* bspline/gsl_bspline.h + * + * Copyright (C) 2006 Patrick Alken + * Copyright (C) 2008 Rhys Ulerich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BSPLINE_H__ +#define __GSL_BSPLINE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t k; /* spline order */ + size_t km1; /* k - 1 (polynomial order) */ + size_t l; /* number of polynomial pieces on interval */ + size_t nbreak; /* number of breakpoints (l + 1) */ + size_t n; /* number of bspline basis functions (l + k - 1) */ + + gsl_vector *knots; /* knots vector */ + gsl_vector *deltal; /* left delta */ + gsl_vector *deltar; /* right delta */ + gsl_vector *B; /* temporary spline results */ + + /* bspline derivative parameters */ + gsl_matrix *A; /* work matrix */ + gsl_matrix *dB; /* temporary derivative results */ +} gsl_bspline_workspace; + +gsl_bspline_workspace * +gsl_bspline_alloc(const size_t k, const size_t nbreak); + +void gsl_bspline_free(gsl_bspline_workspace *w); + +size_t gsl_bspline_ncoeffs(gsl_bspline_workspace * w); +size_t gsl_bspline_order(gsl_bspline_workspace * w); +size_t gsl_bspline_nbreak(gsl_bspline_workspace * w); +double gsl_bspline_breakpoint(size_t i, gsl_bspline_workspace * w); +double gsl_bspline_greville_abscissa(size_t i, gsl_bspline_workspace *w); + +int +gsl_bspline_knots(const gsl_vector *breakpts, gsl_bspline_workspace *w); + +int gsl_bspline_knots_uniform(const double a, const double b, + gsl_bspline_workspace *w); + +int +gsl_bspline_knots_greville(const gsl_vector *abscissae, + gsl_bspline_workspace *w, + double *abserr); + +int +gsl_bspline_eval(const double x, gsl_vector *B, + gsl_bspline_workspace *w); + +int +gsl_bspline_eval_nonzero(const double x, + gsl_vector *Bk, + size_t *istart, + size_t *iend, + gsl_bspline_workspace *w); + +int +gsl_bspline_deriv_eval(const double x, + const size_t nderiv, + gsl_matrix *dB, + gsl_bspline_workspace *w); + +int +gsl_bspline_deriv_eval_nonzero(const double x, + const size_t nderiv, + gsl_matrix *dB, + size_t *istart, + size_t *iend, + gsl_bspline_workspace *w); + +__END_DECLS + +#endif /* __GSL_BSPLINE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_bst.h b/ChaosDataPlayer/GSL/include/gsl/gsl_bst.h new file mode 100644 index 0000000..7b18a6c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_bst.h @@ -0,0 +1,117 @@ +/* bst/gsl_bst.h + * + * Copyright (C) 2018, 2019 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BST_H__ +#define __GSL_BST_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* type of binary search tree */ +typedef struct +{ + const char *name; + const size_t node_size; + int (*init)(const gsl_bst_allocator * allocator, + gsl_bst_cmp_function * compare, void * params, void * vtable); + size_t (*nodes) (const void * vtable); + void * (*insert) (void * item, void * vtable); + void * (*find) (const void *item, const void * vtable); + void * (*remove) (const void *item, void * vtable); + int (*empty) (void * vtable); + int (*trav_init) (void * vtrav, const void * vtable); + void * (*trav_first) (void * vtrav, const void * vtable); + void * (*trav_last) (void * vtrav, const void * vtable); + void * (*trav_find) (const void * item, void * vtrav, const void * vtable); + void * (*trav_insert) (void * item, void * vtrav, void * vtable); + void * (*trav_copy) (void * vtrav, const void * vsrc); + void * (*trav_next) (void * vtrav); + void * (*trav_prev) (void * vtrav); + void * (*trav_cur) (const void * vtrav); + void * (*trav_replace) (void * vtrav, void * new_item); +} gsl_bst_type; + +typedef struct +{ + const gsl_bst_type * type; /* binary search tree type */ + union + { + gsl_bst_avl_table avl_table; + gsl_bst_rb_table rb_table; + } table; +} gsl_bst_workspace; + +typedef struct +{ + const gsl_bst_type * type; /* binary search tree type */ + union + { + gsl_bst_avl_traverser avl_trav; + gsl_bst_rb_traverser rb_trav; + } trav_data; +} gsl_bst_trav; + +/* tree types */ +GSL_VAR const gsl_bst_type * gsl_bst_avl; +GSL_VAR const gsl_bst_type * gsl_bst_rb; + +/* + * Prototypes + */ + +gsl_bst_workspace * gsl_bst_alloc(const gsl_bst_type * T, const gsl_bst_allocator * allocator, + gsl_bst_cmp_function * compare, void * params); +void gsl_bst_free(gsl_bst_workspace * w); +int gsl_bst_empty(gsl_bst_workspace * w); +void * gsl_bst_insert(void * item, gsl_bst_workspace * w); +void * gsl_bst_find(const void * item, const gsl_bst_workspace * w); +void * gsl_bst_remove(const void * item, gsl_bst_workspace * w); +size_t gsl_bst_nodes(const gsl_bst_workspace * w); +size_t gsl_bst_node_size(const gsl_bst_workspace * w); +const char * gsl_bst_name(const gsl_bst_workspace * w); + +int gsl_bst_trav_init(gsl_bst_trav * trav, const gsl_bst_workspace * w); +void * gsl_bst_trav_first(gsl_bst_trav * trav, const gsl_bst_workspace * w); +void * gsl_bst_trav_last (gsl_bst_trav * trav, const gsl_bst_workspace * w); +void * gsl_bst_trav_find (const void * item, gsl_bst_trav * trav, const gsl_bst_workspace * w); +void * gsl_bst_trav_insert (void * item, gsl_bst_trav * trav, gsl_bst_workspace * w); +void * gsl_bst_trav_copy(gsl_bst_trav * dest, const gsl_bst_trav * src); +void * gsl_bst_trav_next(gsl_bst_trav * trav); +void * gsl_bst_trav_prev(gsl_bst_trav * trav); +void * gsl_bst_trav_cur(const gsl_bst_trav * trav); +void * gsl_bst_trav_replace (gsl_bst_trav * trav, void * new_item); + +__END_DECLS + +#endif /* __GSL_BST_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_bst_avl.h b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_avl.h new file mode 100644 index 0000000..99c4a89 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_avl.h @@ -0,0 +1,73 @@ +/* bst/gsl_bst_avl.h + * + * Copyright (C) 2018 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BST_AVL_H__ +#define __GSL_BST_AVL_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +#ifndef GSL_BST_AVL_MAX_HEIGHT +#define GSL_BST_AVL_MAX_HEIGHT 32 +#endif + +/* AVL node */ +struct gsl_bst_avl_node +{ + struct gsl_bst_avl_node *avl_link[2]; /* subtrees */ + void *avl_data; /* pointer to data */ + signed char avl_balance; /* balance factor */ +}; + +/* tree data structure */ +typedef struct +{ + struct gsl_bst_avl_node *avl_root; /* tree's root */ + gsl_bst_cmp_function *avl_compare; /* comparison function */ + void *avl_param; /* extra argument to |avl_compare| */ + const gsl_bst_allocator *avl_alloc; /* memory allocator */ + size_t avl_count; /* number of items in tree */ + unsigned long avl_generation; /* generation number */ +} gsl_bst_avl_table; + +/* AVL traverser structure */ +typedef struct +{ + const gsl_bst_avl_table *avl_table; /* tree being traversed */ + struct gsl_bst_avl_node *avl_node; /* current node in tree */ + struct gsl_bst_avl_node *avl_stack[GSL_BST_AVL_MAX_HEIGHT]; /* all the nodes above |avl_node| */ + size_t avl_height; /* number of nodes in |avl_parent| */ + unsigned long avl_generation; /* generation number */ +} gsl_bst_avl_traverser; + +__END_DECLS + +#endif /* __GSL_BST_AVL_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_bst_rb.h b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_rb.h new file mode 100644 index 0000000..05e0c0f --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_rb.h @@ -0,0 +1,74 @@ +/* bst/gsl_bst_rb.h + * + * Copyright (C) 2018 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BST_RB_H__ +#define __GSL_BST_RB_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +#ifndef GSL_BST_RB_MAX_HEIGHT +#define GSL_BST_RB_MAX_HEIGHT 48 +#endif + +/* red-black node */ +struct gsl_bst_rb_node +{ + struct gsl_bst_rb_node *rb_link[2]; /* subtrees */ + void *rb_data; /* pointer to data */ + unsigned char rb_color; /* color */ +}; + +/* red-black tree data structure */ +typedef struct +{ + struct gsl_bst_rb_node *rb_root; /* tree's root */ + gsl_bst_cmp_function *rb_compare; /* comparison function */ + void *rb_param; /* extra argument to |rb_compare| */ + const gsl_bst_allocator *rb_alloc; /* memory allocator */ + size_t rb_count; /* number of items in tree */ + unsigned long rb_generation; /* generation number */ +} gsl_bst_rb_table; + +/* red-black traverser structure */ +typedef struct +{ + const gsl_bst_rb_table *rb_table; /* tree being traversed */ + struct gsl_bst_rb_node *rb_node; /* current node in tree */ + struct gsl_bst_rb_node *rb_stack[GSL_BST_RB_MAX_HEIGHT]; + /* all the nodes above |rb_node| */ + size_t rb_height; /* number of nodes in |rb_parent| */ + unsigned long rb_generation; /* generation number */ +} gsl_bst_rb_traverser; + +__END_DECLS + +#endif /* __GSL_BST_RB_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_bst_types.h b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_types.h new file mode 100644 index 0000000..c03adf3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_bst_types.h @@ -0,0 +1,48 @@ +/* bst/gsl_bst_types.h + * + * Copyright (C) 2019 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_BST_TYPES_H__ +#define __GSL_BST_TYPES_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef int gsl_bst_cmp_function (const void * a, const void * b, void * params); + +/* allocation routines */ +typedef struct +{ + void * (*alloc) (size_t size, void * params); + void (*free) (void * block, void * params); +} gsl_bst_allocator; + +__END_DECLS + +#endif /* __GSL_BST_TYPES_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_cblas.h b/ChaosDataPlayer/GSL/include/gsl/gsl_cblas.h new file mode 100644 index 0000000..e90e3b0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_cblas.h @@ -0,0 +1,606 @@ +/* blas/gsl_cblas.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This is a copy of the CBLAS standard header. + * We carry this around so we do not have to + * break our model for flexible BLAS functionality. + */ + +#ifndef __GSL_CBLAS_H__ +#define __GSL_CBLAS_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS /* empty */ +#define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * Enumerated and derived types + */ +#define CBLAS_INDEX size_t /* this may vary between platforms */ + +enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102}; +enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113}; +enum CBLAS_UPLO {CblasUpper=121, CblasLower=122}; +enum CBLAS_DIAG {CblasNonUnit=131, CblasUnit=132}; +enum CBLAS_SIDE {CblasLeft=141, CblasRight=142}; + +/* + * =========================================================================== + * Prototypes for level 1 BLAS functions (complex are recast as routines) + * =========================================================================== + */ +float cblas_sdsdot(const int N, const float alpha, const float *X, + const int incX, const float *Y, const int incY); +double cblas_dsdot(const int N, const float *X, const int incX, const float *Y, + const int incY); +float cblas_sdot(const int N, const float *X, const int incX, + const float *Y, const int incY); +double cblas_ddot(const int N, const double *X, const int incX, + const double *Y, const int incY); + +/* + * Functions having prefixes Z and C only + */ +void cblas_cdotu_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotu); +void cblas_cdotc_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotc); + +void cblas_zdotu_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotu); +void cblas_zdotc_sub(const int N, const void *X, const int incX, + const void *Y, const int incY, void *dotc); + + +/* + * Functions having prefixes S D SC DZ + */ +float cblas_snrm2(const int N, const float *X, const int incX); +float cblas_sasum(const int N, const float *X, const int incX); + +double cblas_dnrm2(const int N, const double *X, const int incX); +double cblas_dasum(const int N, const double *X, const int incX); + +float cblas_scnrm2(const int N, const void *X, const int incX); +float cblas_scasum(const int N, const void *X, const int incX); + +double cblas_dznrm2(const int N, const void *X, const int incX); +double cblas_dzasum(const int N, const void *X, const int incX); + + +/* + * Functions having standard 4 prefixes (S D C Z) + */ +CBLAS_INDEX cblas_isamax(const int N, const float *X, const int incX); +CBLAS_INDEX cblas_idamax(const int N, const double *X, const int incX); +CBLAS_INDEX cblas_icamax(const int N, const void *X, const int incX); +CBLAS_INDEX cblas_izamax(const int N, const void *X, const int incX); + +/* + * =========================================================================== + * Prototypes for level 1 BLAS routines + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (s, d, c, z) + */ +void cblas_sswap(const int N, float *X, const int incX, + float *Y, const int incY); +void cblas_scopy(const int N, const float *X, const int incX, + float *Y, const int incY); +void cblas_saxpy(const int N, const float alpha, const float *X, + const int incX, float *Y, const int incY); + +void cblas_dswap(const int N, double *X, const int incX, + double *Y, const int incY); +void cblas_dcopy(const int N, const double *X, const int incX, + double *Y, const int incY); +void cblas_daxpy(const int N, const double alpha, const double *X, + const int incX, double *Y, const int incY); + +void cblas_cswap(const int N, void *X, const int incX, + void *Y, const int incY); +void cblas_ccopy(const int N, const void *X, const int incX, + void *Y, const int incY); +void cblas_caxpy(const int N, const void *alpha, const void *X, + const int incX, void *Y, const int incY); + +void cblas_zswap(const int N, void *X, const int incX, + void *Y, const int incY); +void cblas_zcopy(const int N, const void *X, const int incX, + void *Y, const int incY); +void cblas_zaxpy(const int N, const void *alpha, const void *X, + const int incX, void *Y, const int incY); + + +/* + * Routines with S and D prefix only + */ +void cblas_srotg(float *a, float *b, float *c, float *s); +void cblas_srotmg(float *d1, float *d2, float *b1, const float b2, float *P); +void cblas_srot(const int N, float *X, const int incX, + float *Y, const int incY, const float c, const float s); +void cblas_srotm(const int N, float *X, const int incX, + float *Y, const int incY, const float *P); + +void cblas_drotg(double *a, double *b, double *c, double *s); +void cblas_drotmg(double *d1, double *d2, double *b1, const double b2, double *P); +void cblas_drot(const int N, double *X, const int incX, + double *Y, const int incY, const double c, const double s); +void cblas_drotm(const int N, double *X, const int incX, + double *Y, const int incY, const double *P); + + +/* + * Routines with S D C Z CS and ZD prefixes + */ +void cblas_sscal(const int N, const float alpha, float *X, const int incX); +void cblas_dscal(const int N, const double alpha, double *X, const int incX); +void cblas_cscal(const int N, const void *alpha, void *X, const int incX); +void cblas_zscal(const int N, const void *alpha, void *X, const int incX); +void cblas_csscal(const int N, const float alpha, void *X, const int incX); +void cblas_zdscal(const int N, const double alpha, void *X, const int incX); + +/* + * =========================================================================== + * Prototypes for level 2 BLAS + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +void cblas_sgemv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const float alpha, const float *A, const int lda, + const float *X, const int incX, const float beta, + float *Y, const int incY); +void cblas_sgbmv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const float alpha, + const float *A, const int lda, const float *X, + const int incX, const float beta, float *Y, const int incY); +void cblas_strmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const float *A, const int lda, + float *X, const int incX); +void cblas_stbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const float *A, const int lda, + float *X, const int incX); +void cblas_stpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const float *Ap, float *X, const int incX); +void cblas_strsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const float *A, const int lda, float *X, + const int incX); +void cblas_stbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const float *A, const int lda, + float *X, const int incX); +void cblas_stpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const float *Ap, float *X, const int incX); + +void cblas_dgemv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const double alpha, const double *A, const int lda, + const double *X, const int incX, const double beta, + double *Y, const int incY); +void cblas_dgbmv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const double alpha, + const double *A, const int lda, const double *X, + const int incX, const double beta, double *Y, const int incY); +void cblas_dtrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const double *A, const int lda, + double *X, const int incX); +void cblas_dtbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const double *A, const int lda, + double *X, const int incX); +void cblas_dtpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const double *Ap, double *X, const int incX); +void cblas_dtrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const double *A, const int lda, double *X, + const int incX); +void cblas_dtbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const double *A, const int lda, + double *X, const int incX); +void cblas_dtpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const double *Ap, double *X, const int incX); + +void cblas_cgemv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *X, const int incX, const void *beta, + void *Y, const int incY); +void cblas_cgbmv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const void *alpha, + const void *A, const int lda, const void *X, + const int incX, const void *beta, void *Y, const int incY); +void cblas_ctrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *A, const int lda, + void *X, const int incX); +void cblas_ctbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ctpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); +void cblas_ctrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *A, const int lda, void *X, + const int incX); +void cblas_ctbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ctpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); + +void cblas_zgemv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *X, const int incX, const void *beta, + void *Y, const int incY); +void cblas_zgbmv(const enum CBLAS_ORDER order, + const enum CBLAS_TRANSPOSE TransA, const int M, const int N, + const int KL, const int KU, const void *alpha, + const void *A, const int lda, const void *X, + const int incX, const void *beta, void *Y, const int incY); +void cblas_ztrmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *A, const int lda, + void *X, const int incX); +void cblas_ztbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ztpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); +void cblas_ztrsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *A, const int lda, void *X, + const int incX); +void cblas_ztbsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const int K, const void *A, const int lda, + void *X, const int incX); +void cblas_ztpsv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_DIAG Diag, + const int N, const void *Ap, void *X, const int incX); + + +/* + * Routines with S and D prefixes only + */ +void cblas_ssymv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *A, + const int lda, const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_ssbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const int K, const float alpha, const float *A, + const int lda, const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_sspmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *Ap, + const float *X, const int incX, + const float beta, float *Y, const int incY); +void cblas_sger(const enum CBLAS_ORDER order, const int M, const int N, + const float alpha, const float *X, const int incX, + const float *Y, const int incY, float *A, const int lda); +void cblas_ssyr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, float *A, const int lda); +void cblas_sspr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, float *Ap); +void cblas_ssyr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, const float *Y, const int incY, float *A, + const int lda); +void cblas_sspr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const float *X, + const int incX, const float *Y, const int incY, float *A); + +void cblas_dsymv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *A, + const int lda, const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dsbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const int K, const double alpha, const double *A, + const int lda, const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dspmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *Ap, + const double *X, const int incX, + const double beta, double *Y, const int incY); +void cblas_dger(const enum CBLAS_ORDER order, const int M, const int N, + const double alpha, const double *X, const int incX, + const double *Y, const int incY, double *A, const int lda); +void cblas_dsyr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, double *A, const int lda); +void cblas_dspr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, double *Ap); +void cblas_dsyr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, const double *Y, const int incY, double *A, + const int lda); +void cblas_dspr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const double *X, + const int incX, const double *Y, const int incY, double *A); + + +/* + * Routines with C and Z prefixes only + */ +void cblas_chemv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_chbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const int K, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_chpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *Ap, + const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_cgeru(const enum CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_cgerc(const enum CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_cher(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const void *X, const int incX, + void *A, const int lda); +void cblas_chpr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const float alpha, const void *X, + const int incX, void *A); +void cblas_cher2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_chpr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *Ap); + +void cblas_zhemv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zhbmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const int K, const void *alpha, const void *A, + const int lda, const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zhpmv(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const void *alpha, const void *Ap, + const void *X, const int incX, + const void *beta, void *Y, const int incY); +void cblas_zgeru(const enum CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zgerc(const enum CBLAS_ORDER order, const int M, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zher(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const void *X, const int incX, + void *A, const int lda); +void cblas_zhpr(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, + const int N, const double alpha, const void *X, + const int incX, void *A); +void cblas_zher2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *A, const int lda); +void cblas_zhpr2(const enum CBLAS_ORDER order, const enum CBLAS_UPLO Uplo, const int N, + const void *alpha, const void *X, const int incX, + const void *Y, const int incY, void *Ap); + +/* + * =========================================================================== + * Prototypes for level 3 BLAS + * =========================================================================== + */ + +/* + * Routines with standard 4 prefixes (S, D, C, Z) + */ +void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const float alpha, const float *A, + const int lda, const float *B, const int ldb, + const float beta, float *C, const int ldc); +void cblas_ssymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const float alpha, const float *A, const int lda, + const float *B, const int ldb, const float beta, + float *C, const int ldc); +void cblas_ssyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const float *A, const int lda, + const float beta, float *C, const int ldc); +void cblas_ssyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const float *A, const int lda, + const float *B, const int ldb, const float beta, + float *C, const int ldc); +void cblas_strmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const float alpha, const float *A, const int lda, + float *B, const int ldb); +void cblas_strsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const float alpha, const float *A, const int lda, + float *B, const int ldb); + +void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const double alpha, const double *A, + const int lda, const double *B, const int ldb, + const double beta, double *C, const int ldc); +void cblas_dsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const double alpha, const double *A, const int lda, + const double *B, const int ldb, const double beta, + double *C, const int ldc); +void cblas_dsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const double *A, const int lda, + const double beta, double *C, const int ldc); +void cblas_dsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const double *A, const int lda, + const double *B, const int ldb, const double beta, + double *C, const int ldc); +void cblas_dtrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const double alpha, const double *A, const int lda, + double *B, const int ldb); +void cblas_dtrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const double alpha, const double *A, const int lda, + double *B, const int ldb); + +void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const void *alpha, const void *A, + const int lda, const void *B, const int ldb, + const void *beta, void *C, const int ldc); +void cblas_csymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_csyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *beta, void *C, const int ldc); +void cblas_csyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_ctrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); +void cblas_ctrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); + +void cblas_zgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_TRANSPOSE TransB, const int M, const int N, + const int K, const void *alpha, const void *A, + const int lda, const void *B, const int ldb, + const void *beta, void *C, const int ldc); +void cblas_zsymm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_zsyrk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *beta, void *C, const int ldc); +void cblas_zsyr2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_ztrmm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); +void cblas_ztrsm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const enum CBLAS_TRANSPOSE TransA, + const enum CBLAS_DIAG Diag, const int M, const int N, + const void *alpha, const void *A, const int lda, + void *B, const int ldb); + + +/* + * Routines with prefixes C and Z only + */ +void cblas_chemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_cherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const float alpha, const void *A, const int lda, + const float beta, void *C, const int ldc); +void cblas_cher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const float beta, + void *C, const int ldc); + +void cblas_zhemm(const enum CBLAS_ORDER Order, const enum CBLAS_SIDE Side, + const enum CBLAS_UPLO Uplo, const int M, const int N, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const void *beta, + void *C, const int ldc); +void cblas_zherk(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const double alpha, const void *A, const int lda, + const double beta, void *C, const int ldc); +void cblas_zher2k(const enum CBLAS_ORDER Order, const enum CBLAS_UPLO Uplo, + const enum CBLAS_TRANSPOSE Trans, const int N, const int K, + const void *alpha, const void *A, const int lda, + const void *B, const int ldb, const double beta, + void *C, const int ldc); + +void cblas_xerbla(int p, const char *rout, const char *form, ...); + +__END_DECLS + +#endif /* __GSL_CBLAS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_cdf.h b/ChaosDataPlayer/GSL/include/gsl/gsl_cdf.h new file mode 100644 index 0000000..2bc3fed --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_cdf.h @@ -0,0 +1,170 @@ +/* cdf/gsl_cdf.h + * + * Copyright (C) 2002 Jason H. Stover. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: J. Stover */ + +#ifndef __GSL_CDF_H__ +#define __GSL_CDF_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_cdf_ugaussian_P (const double x); +double gsl_cdf_ugaussian_Q (const double x); + +double gsl_cdf_ugaussian_Pinv (const double P); +double gsl_cdf_ugaussian_Qinv (const double Q); + +double gsl_cdf_gaussian_P (const double x, const double sigma); +double gsl_cdf_gaussian_Q (const double x, const double sigma); + +double gsl_cdf_gaussian_Pinv (const double P, const double sigma); +double gsl_cdf_gaussian_Qinv (const double Q, const double sigma); + +double gsl_cdf_gamma_P (const double x, const double a, const double b); +double gsl_cdf_gamma_Q (const double x, const double a, const double b); + +double gsl_cdf_gamma_Pinv (const double P, const double a, const double b); +double gsl_cdf_gamma_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_cauchy_P (const double x, const double a); +double gsl_cdf_cauchy_Q (const double x, const double a); + +double gsl_cdf_cauchy_Pinv (const double P, const double a); +double gsl_cdf_cauchy_Qinv (const double Q, const double a); + +double gsl_cdf_laplace_P (const double x, const double a); +double gsl_cdf_laplace_Q (const double x, const double a); + +double gsl_cdf_laplace_Pinv (const double P, const double a); +double gsl_cdf_laplace_Qinv (const double Q, const double a); + +double gsl_cdf_rayleigh_P (const double x, const double sigma); +double gsl_cdf_rayleigh_Q (const double x, const double sigma); + +double gsl_cdf_rayleigh_Pinv (const double P, const double sigma); +double gsl_cdf_rayleigh_Qinv (const double Q, const double sigma); + +double gsl_cdf_chisq_P (const double x, const double nu); +double gsl_cdf_chisq_Q (const double x, const double nu); + +double gsl_cdf_chisq_Pinv (const double P, const double nu); +double gsl_cdf_chisq_Qinv (const double Q, const double nu); + +double gsl_cdf_exponential_P (const double x, const double mu); +double gsl_cdf_exponential_Q (const double x, const double mu); + +double gsl_cdf_exponential_Pinv (const double P, const double mu); +double gsl_cdf_exponential_Qinv (const double Q, const double mu); + +double gsl_cdf_exppow_P (const double x, const double a, const double b); +double gsl_cdf_exppow_Q (const double x, const double a, const double b); + +double gsl_cdf_tdist_P (const double x, const double nu); +double gsl_cdf_tdist_Q (const double x, const double nu); + +double gsl_cdf_tdist_Pinv (const double P, const double nu); +double gsl_cdf_tdist_Qinv (const double Q, const double nu); + +double gsl_cdf_fdist_P (const double x, const double nu1, const double nu2); +double gsl_cdf_fdist_Q (const double x, const double nu1, const double nu2); + +double gsl_cdf_fdist_Pinv (const double P, const double nu1, const double nu2); +double gsl_cdf_fdist_Qinv (const double Q, const double nu1, const double nu2); + +double gsl_cdf_beta_P (const double x, const double a, const double b); +double gsl_cdf_beta_Q (const double x, const double a, const double b); + +double gsl_cdf_beta_Pinv (const double P, const double a, const double b); +double gsl_cdf_beta_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_flat_P (const double x, const double a, const double b); +double gsl_cdf_flat_Q (const double x, const double a, const double b); + +double gsl_cdf_flat_Pinv (const double P, const double a, const double b); +double gsl_cdf_flat_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_lognormal_P (const double x, const double zeta, const double sigma); +double gsl_cdf_lognormal_Q (const double x, const double zeta, const double sigma); + +double gsl_cdf_lognormal_Pinv (const double P, const double zeta, const double sigma); +double gsl_cdf_lognormal_Qinv (const double Q, const double zeta, const double sigma); + +double gsl_cdf_gumbel1_P (const double x, const double a, const double b); +double gsl_cdf_gumbel1_Q (const double x, const double a, const double b); + +double gsl_cdf_gumbel1_Pinv (const double P, const double a, const double b); +double gsl_cdf_gumbel1_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_gumbel2_P (const double x, const double a, const double b); +double gsl_cdf_gumbel2_Q (const double x, const double a, const double b); + +double gsl_cdf_gumbel2_Pinv (const double P, const double a, const double b); +double gsl_cdf_gumbel2_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_weibull_P (const double x, const double a, const double b); +double gsl_cdf_weibull_Q (const double x, const double a, const double b); + +double gsl_cdf_weibull_Pinv (const double P, const double a, const double b); +double gsl_cdf_weibull_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_pareto_P (const double x, const double a, const double b); +double gsl_cdf_pareto_Q (const double x, const double a, const double b); + +double gsl_cdf_pareto_Pinv (const double P, const double a, const double b); +double gsl_cdf_pareto_Qinv (const double Q, const double a, const double b); + +double gsl_cdf_logistic_P (const double x, const double a); +double gsl_cdf_logistic_Q (const double x, const double a); + +double gsl_cdf_logistic_Pinv (const double P, const double a); +double gsl_cdf_logistic_Qinv (const double Q, const double a); + +double gsl_cdf_binomial_P (const unsigned int k, const double p, const unsigned int n); +double gsl_cdf_binomial_Q (const unsigned int k, const double p, const unsigned int n); + +double gsl_cdf_poisson_P (const unsigned int k, const double mu); +double gsl_cdf_poisson_Q (const unsigned int k, const double mu); + +double gsl_cdf_geometric_P (const unsigned int k, const double p); +double gsl_cdf_geometric_Q (const unsigned int k, const double p); + +double gsl_cdf_negative_binomial_P (const unsigned int k, const double p, const double n); +double gsl_cdf_negative_binomial_Q (const unsigned int k, const double p, const double n); + +double gsl_cdf_pascal_P (const unsigned int k, const double p, const unsigned int n); +double gsl_cdf_pascal_Q (const unsigned int k, const double p, const unsigned int n); + +double gsl_cdf_hypergeometric_P (const unsigned int k, const unsigned int n1, + const unsigned int n2, const unsigned int t); +double gsl_cdf_hypergeometric_Q (const unsigned int k, const unsigned int n1, + const unsigned int n2, const unsigned int t); + +__END_DECLS + +#endif /* __GSL_CDF_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_chebyshev.h b/ChaosDataPlayer/GSL/include/gsl/gsl_chebyshev.h new file mode 100644 index 0000000..98a6980 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_chebyshev.h @@ -0,0 +1,134 @@ +/* cheb/gsl_chebyshev.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CHEBYSHEV_H__ +#define __GSL_CHEBYSHEV_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* data for a Chebyshev series over a given interval */ + +struct gsl_cheb_series_struct { + + double * c; /* coefficients */ + size_t order; /* order of expansion */ + double a; /* lower interval point */ + double b; /* upper interval point */ + + /* The following exists (mostly) for the benefit + * of the implementation. It is an effective single + * precision order, for use in single precision + * evaluation. Users can use it if they like, but + * only they know how to calculate it, since it is + * specific to the approximated function. By default, + * order_sp = order. + * It is used explicitly only by the gsl_cheb_eval_mode + * functions, which are not meant for casual use. + */ + size_t order_sp; + + /* Additional elements not used by specfunc */ + + double * f; /* function evaluated at chebyschev points */ +}; +typedef struct gsl_cheb_series_struct gsl_cheb_series; + + +/* Calculate a Chebyshev series of specified order over + * a specified interval, for a given function. + * Return 0 on failure. + */ +gsl_cheb_series * gsl_cheb_alloc(const size_t order); + +/* Free a Chebyshev series previously calculated with gsl_cheb_alloc(). + */ +void gsl_cheb_free(gsl_cheb_series * cs); + +/* Calculate a Chebyshev series using the storage provided. + * Uses the interval (a,b) and the order with which it + * was initially created. + * + */ +int gsl_cheb_init(gsl_cheb_series * cs, const gsl_function * func, + const double a, const double b); + +/* Return the order, size of coefficient array and coefficient array ptr */ +size_t gsl_cheb_order (const gsl_cheb_series * cs); +size_t gsl_cheb_size (const gsl_cheb_series * cs); +double *gsl_cheb_coeffs (const gsl_cheb_series * cs); + +/* Evaluate a Chebyshev series at a given point. + * No errors can occur for a struct obtained from gsl_cheb_new(). + */ +double gsl_cheb_eval(const gsl_cheb_series * cs, const double x); +int gsl_cheb_eval_err(const gsl_cheb_series * cs, const double x, + double * result, double * abserr); + + +/* Evaluate a Chebyshev series at a given point, to (at most) the given order. + * No errors can occur for a struct obtained from gsl_cheb_new(). + */ +double gsl_cheb_eval_n(const gsl_cheb_series * cs, const size_t order, + const double x); +int gsl_cheb_eval_n_err(const gsl_cheb_series * cs, const size_t order, + const double x, double * result, double * abserr); + + +/* Evaluate a Chebyshev series at a given point, using the default + * order for double precision mode(s) and the single precision + * order for other modes. + * No errors can occur for a struct obtained from gsl_cheb_new(). + */ +double gsl_cheb_eval_mode(const gsl_cheb_series * cs, const double x, gsl_mode_t mode); +int gsl_cheb_eval_mode_e(const gsl_cheb_series * cs, const double x, gsl_mode_t mode, double * result, double * abserr); + + + +/* Compute the derivative of a Chebyshev series. + */ +int gsl_cheb_calc_deriv(gsl_cheb_series * deriv, const gsl_cheb_series * cs); + +/* Compute the integral of a Chebyshev series. The + * integral is fixed by the condition that it equals zero at + * the left end-point, ie it is precisely + * Integrate[cs(t; a,b), {t, a, x}] + */ +int gsl_cheb_calc_integ(gsl_cheb_series * integ, const gsl_cheb_series * cs); + + + + +__END_DECLS + +#endif /* __GSL_CHEBYSHEV_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_check_range.h b/ChaosDataPlayer/GSL/include/gsl/gsl_check_range.h new file mode 100644 index 0000000..d110b6b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_check_range.h @@ -0,0 +1,57 @@ +/* vector/gsl_check_range.h + * + * Copyright (C) 2003, 2004, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CHECK_RANGE_H__ +#define __GSL_CHECK_RANGE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +GSL_VAR int gsl_check_range; + +/* Turn range checking on by default, unless the user defines + GSL_RANGE_CHECK_OFF, or defines GSL_RANGE_CHECK to 0 explicitly */ + +#ifdef GSL_RANGE_CHECK_OFF +# ifndef GSL_RANGE_CHECK +# define GSL_RANGE_CHECK 0 +# else +# error "cannot set both GSL_RANGE_CHECK and GSL_RANGE_CHECK_OFF" +# endif +#else +# ifndef GSL_RANGE_CHECK +# define GSL_RANGE_CHECK 1 +# endif +#endif + +__END_DECLS + +#endif /* __GSL_CHECK_RANGE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_combination.h b/ChaosDataPlayer/GSL/include/gsl/gsl_combination.h new file mode 100644 index 0000000..69de7cf --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_combination.h @@ -0,0 +1,92 @@ +/* combination/gsl_combination.h + * based on permutation/gsl_permutation.h by Brian Gough + * + * Copyright (C) 2001 Szymon Jaroszewicz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_COMBINATION_H__ +#define __GSL_COMBINATION_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_combination_struct +{ + size_t n; + size_t k; + size_t *data; +}; + +typedef struct gsl_combination_struct gsl_combination; + +gsl_combination *gsl_combination_alloc (const size_t n, const size_t k); +gsl_combination *gsl_combination_calloc (const size_t n, const size_t k); +void gsl_combination_init_first (gsl_combination * c); +void gsl_combination_init_last (gsl_combination * c); +void gsl_combination_free (gsl_combination * c); +int gsl_combination_memcpy (gsl_combination * dest, const gsl_combination * src); + +int gsl_combination_fread (FILE * stream, gsl_combination * c); +int gsl_combination_fwrite (FILE * stream, const gsl_combination * c); +int gsl_combination_fscanf (FILE * stream, gsl_combination * c); +int gsl_combination_fprintf (FILE * stream, const gsl_combination * c, const char *format); + +size_t gsl_combination_n (const gsl_combination * c); +size_t gsl_combination_k (const gsl_combination * c); +size_t * gsl_combination_data (const gsl_combination * c); + +int gsl_combination_valid (gsl_combination * c); +int gsl_combination_next (gsl_combination * c); +int gsl_combination_prev (gsl_combination * c); + +INLINE_DECL size_t gsl_combination_get (const gsl_combination * c, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +size_t +gsl_combination_get (const gsl_combination * c, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= c->k)) /* size_t is unsigned, can't be negative */ + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return c->data[i]; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_COMBINATION_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_complex.h b/ChaosDataPlayer/GSL/include/gsl/gsl_complex.h new file mode 100644 index 0000000..347ac87 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_complex.h @@ -0,0 +1,144 @@ +/* complex/gsl_complex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * Copyright (C) 2020, 2021 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_COMPLEX_H__ +#define __GSL_COMPLEX_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* two consecutive built-in types as a complex number */ +typedef double * gsl_complex_packed ; +typedef float * gsl_complex_packed_float ; +typedef long double * gsl_complex_packed_long_double ; + +typedef const double * gsl_const_complex_packed ; +typedef const float * gsl_const_complex_packed_float ; +typedef const long double * gsl_const_complex_packed_long_double ; + + +/* 2N consecutive built-in types as N complex numbers */ +typedef double * gsl_complex_packed_array ; +typedef float * gsl_complex_packed_array_float ; +typedef long double * gsl_complex_packed_array_long_double ; + +typedef const double * gsl_const_complex_packed_array ; +typedef const float * gsl_const_complex_packed_array_float ; +typedef const long double * gsl_const_complex_packed_array_long_double ; + + +/* Yes... this seems weird. Trust us. The point is just that + sometimes you want to make it obvious that something is + an output value. The fact that it lacks a 'const' may not + be enough of a clue for people in some contexts. + */ +typedef double * gsl_complex_packed_ptr ; +typedef float * gsl_complex_packed_float_ptr ; +typedef long double * gsl_complex_packed_long_double_ptr ; + +typedef const double * gsl_const_complex_packed_ptr ; +typedef const float * gsl_const_complex_packed_float_ptr ; +typedef const long double * gsl_const_complex_packed_long_double_ptr ; + +/* + * If is included, use the C99 complex type. Otherwise + * define a type bit-compatible with C99 complex. The GSL_REAL and GSL_IMAG + * macros require C11 functionality also (_Generic) + */ + +/* older gcc compilers claim to be C11 compliant but do not support _Generic */ +#if defined(__GNUC__) && (__GNUC__ < 7) +# define GSL_COMPLEX_LEGACY 1 +#endif + +#if !defined(GSL_COMPLEX_LEGACY) && \ + defined(_Complex_I) && \ + defined(complex) && \ + defined(I) && \ + defined(__STDC__) && (__STDC__ == 1) && \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ + +# define GSL_COMPLEX_DEFINE(R, C) typedef R _Complex C ; + +# define GSL_COMPLEX_P(zp) (&(zp)) +# define GSL_COMPLEX_EQ(z1,z2) ((z1) == (z2)) +# define GSL_SET_COMPLEX(zp,x,y) (*(zp) = (x) + I * (y)) + +# define GSL_REAL(z) (_Generic((z), \ + complex float : ((float *) &(z)), \ + complex double : ((double *) &(z)), \ + complex long double : ((long double *) &(z)))[0]) + +# define GSL_IMAG(z) (_Generic((z), \ + complex float : ((float *) &(z)), \ + complex double : ((double *) &(z)), \ + complex long double : ((long double *) &(z)))[1]) + +# define GSL_COMPLEX_P_REAL(zp) GSL_REAL(*(zp)) +# define GSL_COMPLEX_P_IMAG(zp) GSL_IMAG(*(zp)) +# define GSL_SET_REAL(zp,x) do { GSL_REAL(*(zp)) = (x); } while(0) +# define GSL_SET_IMAG(zp,x) do { GSL_IMAG(*(zp)) = (x); } while(0) + +#else /* legacy complex definitions */ + +/* + * According to the C17 standard, 6.2.5 paragraph 13: + * + * "Each complex type has the same representation and alignment requirements + * as an array type containing exactly two elements of the corresponding real + * type; the first element is equal to the real part, and the second element to + * the imaginary part, of the complex number." + */ + +/*# define GSL_COMPLEX_DEFINE(R, C) typedef R C[2]*/ +# define GSL_COMPLEX_DEFINE(R, C) typedef struct { R dat[2]; } C ; + +# define GSL_REAL(z) ((z).dat[0]) +# define GSL_IMAG(z) ((z).dat[1]) +# define GSL_COMPLEX_P(zp) ((zp)->dat) +# define GSL_COMPLEX_P_REAL(zp) ((zp)->dat[0]) +# define GSL_COMPLEX_P_IMAG(zp) ((zp)->dat[1]) +# define GSL_COMPLEX_EQ(z1,z2) (((z1).dat[0] == (z2).dat[0]) && ((z1).dat[1] == (z2).dat[1])) + +# define GSL_SET_COMPLEX(zp,x,y) do {(zp)->dat[0]=(x); (zp)->dat[1]=(y);} while(0) +# define GSL_SET_REAL(zp,x) do {(zp)->dat[0]=(x);} while(0) +# define GSL_SET_IMAG(zp,y) do {(zp)->dat[1]=(y);} while(0) + +#endif + +GSL_COMPLEX_DEFINE(double, gsl_complex) +GSL_COMPLEX_DEFINE(long double, gsl_complex_long_double) +GSL_COMPLEX_DEFINE(float, gsl_complex_float) + +#define GSL_SET_COMPLEX_PACKED(zp,n,x,y) do {*((zp)+2*(n))=(x); *((zp)+(2*(n)+1))=(y);} while(0) + +__END_DECLS + +#endif /* __GSL_COMPLEX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_complex_math.h b/ChaosDataPlayer/GSL/include/gsl/gsl_complex_math.h new file mode 100644 index 0000000..ad8d076 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_complex_math.h @@ -0,0 +1,142 @@ +/* complex/gsl_complex_math.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Jorma Olavi Thtinen, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_COMPLEX_MATH_H__ +#define __GSL_COMPLEX_MATH_H__ +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS /* empty */ +#define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Complex numbers */ + +gsl_complex gsl_complex_polar (double r, double theta); /* r= r e^(i theta) */ + +INLINE_DECL gsl_complex gsl_complex_rect (double x, double y); /* r= real+i*imag */ + +#ifdef HAVE_INLINE +INLINE_FUN gsl_complex +gsl_complex_rect (double x, double y) +{ /* return z = x + i y */ + gsl_complex z; + GSL_SET_COMPLEX (&z, x, y); + return z; +} +#endif + +#define GSL_COMPLEX_ONE (gsl_complex_rect(1.0,0.0)) +#define GSL_COMPLEX_ZERO (gsl_complex_rect(0.0,0.0)) +#define GSL_COMPLEX_NEGONE (gsl_complex_rect(-1.0,0.0)) + +/* Properties of complex numbers */ + +double gsl_complex_arg (gsl_complex z); /* return arg(z), -pi< arg(z) <=+pi */ +double gsl_complex_abs (gsl_complex z); /* return |z| */ +double gsl_complex_abs2 (gsl_complex z); /* return |z|^2 */ +double gsl_complex_logabs (gsl_complex z); /* return log|z| */ + +/* Complex arithmetic operators */ + +gsl_complex gsl_complex_add (gsl_complex a, gsl_complex b); /* r=a+b */ +gsl_complex gsl_complex_sub (gsl_complex a, gsl_complex b); /* r=a-b */ +gsl_complex gsl_complex_mul (gsl_complex a, gsl_complex b); /* r=a*b */ +gsl_complex gsl_complex_div (gsl_complex a, gsl_complex b); /* r=a/b */ + +gsl_complex gsl_complex_add_real (gsl_complex a, double x); /* r=a+x */ +gsl_complex gsl_complex_sub_real (gsl_complex a, double x); /* r=a-x */ +gsl_complex gsl_complex_mul_real (gsl_complex a, double x); /* r=a*x */ +gsl_complex gsl_complex_div_real (gsl_complex a, double x); /* r=a/x */ + +gsl_complex gsl_complex_add_imag (gsl_complex a, double y); /* r=a+iy */ +gsl_complex gsl_complex_sub_imag (gsl_complex a, double y); /* r=a-iy */ +gsl_complex gsl_complex_mul_imag (gsl_complex a, double y); /* r=a*iy */ +gsl_complex gsl_complex_div_imag (gsl_complex a, double y); /* r=a/iy */ + +gsl_complex gsl_complex_conjugate (gsl_complex z); /* r=conj(z) */ +gsl_complex gsl_complex_inverse (gsl_complex a); /* r=1/a */ +gsl_complex gsl_complex_negative (gsl_complex a); /* r=-a */ + +/* Elementary Complex Functions */ + +gsl_complex gsl_complex_sqrt (gsl_complex z); /* r=sqrt(z) */ +gsl_complex gsl_complex_sqrt_real (double x); /* r=sqrt(x) (x<0 ok) */ + +gsl_complex gsl_complex_pow (gsl_complex a, gsl_complex b); /* r=a^b */ +gsl_complex gsl_complex_pow_real (gsl_complex a, double b); /* r=a^b */ + +gsl_complex gsl_complex_exp (gsl_complex a); /* r=exp(a) */ +gsl_complex gsl_complex_log (gsl_complex a); /* r=log(a) (base e) */ +gsl_complex gsl_complex_log10 (gsl_complex a); /* r=log10(a) (base 10) */ +gsl_complex gsl_complex_log_b (gsl_complex a, gsl_complex b); /* r=log_b(a) (base=b) */ + +/* Complex Trigonometric Functions */ + +gsl_complex gsl_complex_sin (gsl_complex a); /* r=sin(a) */ +gsl_complex gsl_complex_cos (gsl_complex a); /* r=cos(a) */ +gsl_complex gsl_complex_sec (gsl_complex a); /* r=sec(a) */ +gsl_complex gsl_complex_csc (gsl_complex a); /* r=csc(a) */ +gsl_complex gsl_complex_tan (gsl_complex a); /* r=tan(a) */ +gsl_complex gsl_complex_cot (gsl_complex a); /* r=cot(a) */ + +/* Inverse Complex Trigonometric Functions */ + +gsl_complex gsl_complex_arcsin (gsl_complex a); /* r=arcsin(a) */ +gsl_complex gsl_complex_arcsin_real (double a); /* r=arcsin(a) */ +gsl_complex gsl_complex_arccos (gsl_complex a); /* r=arccos(a) */ +gsl_complex gsl_complex_arccos_real (double a); /* r=arccos(a) */ +gsl_complex gsl_complex_arcsec (gsl_complex a); /* r=arcsec(a) */ +gsl_complex gsl_complex_arcsec_real (double a); /* r=arcsec(a) */ +gsl_complex gsl_complex_arccsc (gsl_complex a); /* r=arccsc(a) */ +gsl_complex gsl_complex_arccsc_real (double a); /* r=arccsc(a) */ +gsl_complex gsl_complex_arctan (gsl_complex a); /* r=arctan(a) */ +gsl_complex gsl_complex_arccot (gsl_complex a); /* r=arccot(a) */ + +/* Complex Hyperbolic Functions */ + +gsl_complex gsl_complex_sinh (gsl_complex a); /* r=sinh(a) */ +gsl_complex gsl_complex_cosh (gsl_complex a); /* r=coshh(a) */ +gsl_complex gsl_complex_sech (gsl_complex a); /* r=sech(a) */ +gsl_complex gsl_complex_csch (gsl_complex a); /* r=csch(a) */ +gsl_complex gsl_complex_tanh (gsl_complex a); /* r=tanh(a) */ +gsl_complex gsl_complex_coth (gsl_complex a); /* r=coth(a) */ + +/* Inverse Complex Hyperbolic Functions */ + +gsl_complex gsl_complex_arcsinh (gsl_complex a); /* r=arcsinh(a) */ +gsl_complex gsl_complex_arccosh (gsl_complex a); /* r=arccosh(a) */ +gsl_complex gsl_complex_arccosh_real (double a); /* r=arccosh(a) */ +gsl_complex gsl_complex_arcsech (gsl_complex a); /* r=arcsech(a) */ +gsl_complex gsl_complex_arccsch (gsl_complex a); /* r=arccsch(a) */ +gsl_complex gsl_complex_arctanh (gsl_complex a); /* r=arctanh(a) */ +gsl_complex gsl_complex_arctanh_real (double a); /* r=arctanh(a) */ +gsl_complex gsl_complex_arccoth (gsl_complex a); /* r=arccoth(a) */ + +__END_DECLS + +#endif /* __GSL_COMPLEX_MATH_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const.h new file mode 100644 index 0000000..5d749dc --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const.h @@ -0,0 +1,31 @@ +/* const/gsl_const.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST__ +#define __GSL_CONST__ + +#include + +#include +#include + +#include +#include + +#endif /* __GSL_CONST__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgs.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgs.h new file mode 100644 index 0000000..ab95b7b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgs.h @@ -0,0 +1,116 @@ +/* const/gsl_const_cgs.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST_CGS__ +#define __GSL_CONST_CGS__ + +#define GSL_CONST_CGS_SPEED_OF_LIGHT (2.99792458e10) /* cm / s */ +#define GSL_CONST_CGS_GRAVITATIONAL_CONSTANT (6.673e-8) /* cm^3 / g s^2 */ +#define GSL_CONST_CGS_PLANCKS_CONSTANT_H (6.62606896e-27) /* g cm^2 / s */ +#define GSL_CONST_CGS_PLANCKS_CONSTANT_HBAR (1.05457162825e-27) /* g cm^2 / s */ +#define GSL_CONST_CGS_ASTRONOMICAL_UNIT (1.49597870691e13) /* cm */ +#define GSL_CONST_CGS_LIGHT_YEAR (9.46053620707e17) /* cm */ +#define GSL_CONST_CGS_PARSEC (3.08567758135e18) /* cm */ +#define GSL_CONST_CGS_GRAV_ACCEL (9.80665e2) /* cm / s^2 */ +#define GSL_CONST_CGS_ELECTRON_VOLT (1.602176487e-12) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_MASS_ELECTRON (9.10938188e-28) /* g */ +#define GSL_CONST_CGS_MASS_MUON (1.88353109e-25) /* g */ +#define GSL_CONST_CGS_MASS_PROTON (1.67262158e-24) /* g */ +#define GSL_CONST_CGS_MASS_NEUTRON (1.67492716e-24) /* g */ +#define GSL_CONST_CGS_RYDBERG (2.17987196968e-11) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_BOLTZMANN (1.3806504e-16) /* g cm^2 / K s^2 */ +#define GSL_CONST_CGS_MOLAR_GAS (8.314472e7) /* g cm^2 / K mol s^2 */ +#define GSL_CONST_CGS_STANDARD_GAS_VOLUME (2.2710981e4) /* cm^3 / mol */ +#define GSL_CONST_CGS_MINUTE (6e1) /* s */ +#define GSL_CONST_CGS_HOUR (3.6e3) /* s */ +#define GSL_CONST_CGS_DAY (8.64e4) /* s */ +#define GSL_CONST_CGS_WEEK (6.048e5) /* s */ +#define GSL_CONST_CGS_INCH (2.54e0) /* cm */ +#define GSL_CONST_CGS_FOOT (3.048e1) /* cm */ +#define GSL_CONST_CGS_YARD (9.144e1) /* cm */ +#define GSL_CONST_CGS_MILE (1.609344e5) /* cm */ +#define GSL_CONST_CGS_NAUTICAL_MILE (1.852e5) /* cm */ +#define GSL_CONST_CGS_FATHOM (1.8288e2) /* cm */ +#define GSL_CONST_CGS_MIL (2.54e-3) /* cm */ +#define GSL_CONST_CGS_POINT (3.52777777778e-2) /* cm */ +#define GSL_CONST_CGS_TEXPOINT (3.51459803515e-2) /* cm */ +#define GSL_CONST_CGS_MICRON (1e-4) /* cm */ +#define GSL_CONST_CGS_ANGSTROM (1e-8) /* cm */ +#define GSL_CONST_CGS_HECTARE (1e8) /* cm^2 */ +#define GSL_CONST_CGS_ACRE (4.04685642241e7) /* cm^2 */ +#define GSL_CONST_CGS_BARN (1e-24) /* cm^2 */ +#define GSL_CONST_CGS_LITER (1e3) /* cm^3 */ +#define GSL_CONST_CGS_US_GALLON (3.78541178402e3) /* cm^3 */ +#define GSL_CONST_CGS_QUART (9.46352946004e2) /* cm^3 */ +#define GSL_CONST_CGS_PINT (4.73176473002e2) /* cm^3 */ +#define GSL_CONST_CGS_CUP (2.36588236501e2) /* cm^3 */ +#define GSL_CONST_CGS_FLUID_OUNCE (2.95735295626e1) /* cm^3 */ +#define GSL_CONST_CGS_TABLESPOON (1.47867647813e1) /* cm^3 */ +#define GSL_CONST_CGS_TEASPOON (4.92892159375e0) /* cm^3 */ +#define GSL_CONST_CGS_CANADIAN_GALLON (4.54609e3) /* cm^3 */ +#define GSL_CONST_CGS_UK_GALLON (4.546092e3) /* cm^3 */ +#define GSL_CONST_CGS_MILES_PER_HOUR (4.4704e1) /* cm / s */ +#define GSL_CONST_CGS_KILOMETERS_PER_HOUR (2.77777777778e1) /* cm / s */ +#define GSL_CONST_CGS_KNOT (5.14444444444e1) /* cm / s */ +#define GSL_CONST_CGS_POUND_MASS (4.5359237e2) /* g */ +#define GSL_CONST_CGS_OUNCE_MASS (2.8349523125e1) /* g */ +#define GSL_CONST_CGS_TON (9.0718474e5) /* g */ +#define GSL_CONST_CGS_METRIC_TON (1e6) /* g */ +#define GSL_CONST_CGS_UK_TON (1.0160469088e6) /* g */ +#define GSL_CONST_CGS_TROY_OUNCE (3.1103475e1) /* g */ +#define GSL_CONST_CGS_CARAT (2e-1) /* g */ +#define GSL_CONST_CGS_UNIFIED_ATOMIC_MASS (1.660538782e-24) /* g */ +#define GSL_CONST_CGS_GRAM_FORCE (9.80665e2) /* cm g / s^2 */ +#define GSL_CONST_CGS_POUND_FORCE (4.44822161526e5) /* cm g / s^2 */ +#define GSL_CONST_CGS_KILOPOUND_FORCE (4.44822161526e8) /* cm g / s^2 */ +#define GSL_CONST_CGS_POUNDAL (1.38255e4) /* cm g / s^2 */ +#define GSL_CONST_CGS_CALORIE (4.1868e7) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_BTU (1.05505585262e10) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_THERM (1.05506e15) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_HORSEPOWER (7.457e9) /* g cm^2 / s^3 */ +#define GSL_CONST_CGS_BAR (1e6) /* g / cm s^2 */ +#define GSL_CONST_CGS_STD_ATMOSPHERE (1.01325e6) /* g / cm s^2 */ +#define GSL_CONST_CGS_TORR (1.33322368421e3) /* g / cm s^2 */ +#define GSL_CONST_CGS_METER_OF_MERCURY (1.33322368421e6) /* g / cm s^2 */ +#define GSL_CONST_CGS_INCH_OF_MERCURY (3.38638815789e4) /* g / cm s^2 */ +#define GSL_CONST_CGS_INCH_OF_WATER (2.490889e3) /* g / cm s^2 */ +#define GSL_CONST_CGS_PSI (6.89475729317e4) /* g / cm s^2 */ +#define GSL_CONST_CGS_POISE (1e0) /* g / cm s */ +#define GSL_CONST_CGS_STOKES (1e0) /* cm^2 / s */ +#define GSL_CONST_CGS_STILB (1e0) /* cd / cm^2 */ +#define GSL_CONST_CGS_LUMEN (1e0) /* cd sr */ +#define GSL_CONST_CGS_LUX (1e-4) /* cd sr / cm^2 */ +#define GSL_CONST_CGS_PHOT (1e0) /* cd sr / cm^2 */ +#define GSL_CONST_CGS_FOOTCANDLE (1.076e-3) /* cd sr / cm^2 */ +#define GSL_CONST_CGS_LAMBERT (1e0) /* cd sr / cm^2 */ +#define GSL_CONST_CGS_FOOTLAMBERT (1.07639104e-3) /* cd sr / cm^2 */ +#define GSL_CONST_CGS_CURIE (3.7e10) /* 1 / s */ +#define GSL_CONST_CGS_ROENTGEN (2.58e-7) /* A s / g */ +#define GSL_CONST_CGS_RAD (1e2) /* cm^2 / s^2 */ +#define GSL_CONST_CGS_SOLAR_MASS (1.98892e33) /* g */ +#define GSL_CONST_CGS_BOHR_RADIUS (5.291772083e-9) /* cm */ +#define GSL_CONST_CGS_NEWTON (1e5) /* cm g / s^2 */ +#define GSL_CONST_CGS_DYNE (1e0) /* cm g / s^2 */ +#define GSL_CONST_CGS_JOULE (1e7) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_ERG (1e0) /* g cm^2 / s^2 */ +#define GSL_CONST_CGS_STEFAN_BOLTZMANN_CONSTANT (5.67040047374e-5) /* g / K^4 s^3 */ +#define GSL_CONST_CGS_THOMSON_CROSS_SECTION (6.65245893699e-25) /* cm^2 */ + +#endif /* __GSL_CONST_CGS__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgsm.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgsm.h new file mode 100644 index 0000000..2047e5e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const_cgsm.h @@ -0,0 +1,122 @@ +/* const/gsl_const_cgsm.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST_CGSM__ +#define __GSL_CONST_CGSM__ + +#define GSL_CONST_CGSM_SPEED_OF_LIGHT (2.99792458e10) /* cm / s */ +#define GSL_CONST_CGSM_GRAVITATIONAL_CONSTANT (6.673e-8) /* cm^3 / g s^2 */ +#define GSL_CONST_CGSM_PLANCKS_CONSTANT_H (6.62606896e-27) /* g cm^2 / s */ +#define GSL_CONST_CGSM_PLANCKS_CONSTANT_HBAR (1.05457162825e-27) /* g cm^2 / s */ +#define GSL_CONST_CGSM_ASTRONOMICAL_UNIT (1.49597870691e13) /* cm */ +#define GSL_CONST_CGSM_LIGHT_YEAR (9.46053620707e17) /* cm */ +#define GSL_CONST_CGSM_PARSEC (3.08567758135e18) /* cm */ +#define GSL_CONST_CGSM_GRAV_ACCEL (9.80665e2) /* cm / s^2 */ +#define GSL_CONST_CGSM_ELECTRON_VOLT (1.602176487e-12) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_MASS_ELECTRON (9.10938188e-28) /* g */ +#define GSL_CONST_CGSM_MASS_MUON (1.88353109e-25) /* g */ +#define GSL_CONST_CGSM_MASS_PROTON (1.67262158e-24) /* g */ +#define GSL_CONST_CGSM_MASS_NEUTRON (1.67492716e-24) /* g */ +#define GSL_CONST_CGSM_RYDBERG (2.17987196968e-11) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_BOLTZMANN (1.3806504e-16) /* g cm^2 / K s^2 */ +#define GSL_CONST_CGSM_MOLAR_GAS (8.314472e7) /* g cm^2 / K mol s^2 */ +#define GSL_CONST_CGSM_STANDARD_GAS_VOLUME (2.2710981e4) /* cm^3 / mol */ +#define GSL_CONST_CGSM_MINUTE (6e1) /* s */ +#define GSL_CONST_CGSM_HOUR (3.6e3) /* s */ +#define GSL_CONST_CGSM_DAY (8.64e4) /* s */ +#define GSL_CONST_CGSM_WEEK (6.048e5) /* s */ +#define GSL_CONST_CGSM_INCH (2.54e0) /* cm */ +#define GSL_CONST_CGSM_FOOT (3.048e1) /* cm */ +#define GSL_CONST_CGSM_YARD (9.144e1) /* cm */ +#define GSL_CONST_CGSM_MILE (1.609344e5) /* cm */ +#define GSL_CONST_CGSM_NAUTICAL_MILE (1.852e5) /* cm */ +#define GSL_CONST_CGSM_FATHOM (1.8288e2) /* cm */ +#define GSL_CONST_CGSM_MIL (2.54e-3) /* cm */ +#define GSL_CONST_CGSM_POINT (3.52777777778e-2) /* cm */ +#define GSL_CONST_CGSM_TEXPOINT (3.51459803515e-2) /* cm */ +#define GSL_CONST_CGSM_MICRON (1e-4) /* cm */ +#define GSL_CONST_CGSM_ANGSTROM (1e-8) /* cm */ +#define GSL_CONST_CGSM_HECTARE (1e8) /* cm^2 */ +#define GSL_CONST_CGSM_ACRE (4.04685642241e7) /* cm^2 */ +#define GSL_CONST_CGSM_BARN (1e-24) /* cm^2 */ +#define GSL_CONST_CGSM_LITER (1e3) /* cm^3 */ +#define GSL_CONST_CGSM_US_GALLON (3.78541178402e3) /* cm^3 */ +#define GSL_CONST_CGSM_QUART (9.46352946004e2) /* cm^3 */ +#define GSL_CONST_CGSM_PINT (4.73176473002e2) /* cm^3 */ +#define GSL_CONST_CGSM_CUP (2.36588236501e2) /* cm^3 */ +#define GSL_CONST_CGSM_FLUID_OUNCE (2.95735295626e1) /* cm^3 */ +#define GSL_CONST_CGSM_TABLESPOON (1.47867647813e1) /* cm^3 */ +#define GSL_CONST_CGSM_TEASPOON (4.92892159375e0) /* cm^3 */ +#define GSL_CONST_CGSM_CANADIAN_GALLON (4.54609e3) /* cm^3 */ +#define GSL_CONST_CGSM_UK_GALLON (4.546092e3) /* cm^3 */ +#define GSL_CONST_CGSM_MILES_PER_HOUR (4.4704e1) /* cm / s */ +#define GSL_CONST_CGSM_KILOMETERS_PER_HOUR (2.77777777778e1) /* cm / s */ +#define GSL_CONST_CGSM_KNOT (5.14444444444e1) /* cm / s */ +#define GSL_CONST_CGSM_POUND_MASS (4.5359237e2) /* g */ +#define GSL_CONST_CGSM_OUNCE_MASS (2.8349523125e1) /* g */ +#define GSL_CONST_CGSM_TON (9.0718474e5) /* g */ +#define GSL_CONST_CGSM_METRIC_TON (1e6) /* g */ +#define GSL_CONST_CGSM_UK_TON (1.0160469088e6) /* g */ +#define GSL_CONST_CGSM_TROY_OUNCE (3.1103475e1) /* g */ +#define GSL_CONST_CGSM_CARAT (2e-1) /* g */ +#define GSL_CONST_CGSM_UNIFIED_ATOMIC_MASS (1.660538782e-24) /* g */ +#define GSL_CONST_CGSM_GRAM_FORCE (9.80665e2) /* cm g / s^2 */ +#define GSL_CONST_CGSM_POUND_FORCE (4.44822161526e5) /* cm g / s^2 */ +#define GSL_CONST_CGSM_KILOPOUND_FORCE (4.44822161526e8) /* cm g / s^2 */ +#define GSL_CONST_CGSM_POUNDAL (1.38255e4) /* cm g / s^2 */ +#define GSL_CONST_CGSM_CALORIE (4.1868e7) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_BTU (1.05505585262e10) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_THERM (1.05506e15) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_HORSEPOWER (7.457e9) /* g cm^2 / s^3 */ +#define GSL_CONST_CGSM_BAR (1e6) /* g / cm s^2 */ +#define GSL_CONST_CGSM_STD_ATMOSPHERE (1.01325e6) /* g / cm s^2 */ +#define GSL_CONST_CGSM_TORR (1.33322368421e3) /* g / cm s^2 */ +#define GSL_CONST_CGSM_METER_OF_MERCURY (1.33322368421e6) /* g / cm s^2 */ +#define GSL_CONST_CGSM_INCH_OF_MERCURY (3.38638815789e4) /* g / cm s^2 */ +#define GSL_CONST_CGSM_INCH_OF_WATER (2.490889e3) /* g / cm s^2 */ +#define GSL_CONST_CGSM_PSI (6.89475729317e4) /* g / cm s^2 */ +#define GSL_CONST_CGSM_POISE (1e0) /* g / cm s */ +#define GSL_CONST_CGSM_STOKES (1e0) /* cm^2 / s */ +#define GSL_CONST_CGSM_STILB (1e0) /* cd / cm^2 */ +#define GSL_CONST_CGSM_LUMEN (1e0) /* cd sr */ +#define GSL_CONST_CGSM_LUX (1e-4) /* cd sr / cm^2 */ +#define GSL_CONST_CGSM_PHOT (1e0) /* cd sr / cm^2 */ +#define GSL_CONST_CGSM_FOOTCANDLE (1.076e-3) /* cd sr / cm^2 */ +#define GSL_CONST_CGSM_LAMBERT (1e0) /* cd sr / cm^2 */ +#define GSL_CONST_CGSM_FOOTLAMBERT (1.07639104e-3) /* cd sr / cm^2 */ +#define GSL_CONST_CGSM_CURIE (3.7e10) /* 1 / s */ +#define GSL_CONST_CGSM_ROENTGEN (2.58e-8) /* abamp s / g */ +#define GSL_CONST_CGSM_RAD (1e2) /* cm^2 / s^2 */ +#define GSL_CONST_CGSM_SOLAR_MASS (1.98892e33) /* g */ +#define GSL_CONST_CGSM_BOHR_RADIUS (5.291772083e-9) /* cm */ +#define GSL_CONST_CGSM_NEWTON (1e5) /* cm g / s^2 */ +#define GSL_CONST_CGSM_DYNE (1e0) /* cm g / s^2 */ +#define GSL_CONST_CGSM_JOULE (1e7) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_ERG (1e0) /* g cm^2 / s^2 */ +#define GSL_CONST_CGSM_STEFAN_BOLTZMANN_CONSTANT (5.67040047374e-5) /* g / K^4 s^3 */ +#define GSL_CONST_CGSM_THOMSON_CROSS_SECTION (6.65245893699e-25) /* cm^2 */ +#define GSL_CONST_CGSM_BOHR_MAGNETON (9.27400899e-21) /* abamp cm^2 */ +#define GSL_CONST_CGSM_NUCLEAR_MAGNETON (5.05078317e-24) /* abamp cm^2 */ +#define GSL_CONST_CGSM_ELECTRON_MAGNETIC_MOMENT (9.28476362e-21) /* abamp cm^2 */ +#define GSL_CONST_CGSM_PROTON_MAGNETIC_MOMENT (1.410606633e-23) /* abamp cm^2 */ +#define GSL_CONST_CGSM_FARADAY (9.64853429775e3) /* abamp s / mol */ +#define GSL_CONST_CGSM_ELECTRON_CHARGE (1.602176487e-20) /* abamp s */ + +#endif /* __GSL_CONST_CGSM__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const_mks.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const_mks.h new file mode 100644 index 0000000..bc60e2a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const_mks.h @@ -0,0 +1,126 @@ +/* const/gsl_const_mks.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST_MKS__ +#define __GSL_CONST_MKS__ + +#define GSL_CONST_MKS_SPEED_OF_LIGHT (2.99792458e8) /* m / s */ +#define GSL_CONST_MKS_GRAVITATIONAL_CONSTANT (6.673e-11) /* m^3 / kg s^2 */ +#define GSL_CONST_MKS_PLANCKS_CONSTANT_H (6.62606896e-34) /* kg m^2 / s */ +#define GSL_CONST_MKS_PLANCKS_CONSTANT_HBAR (1.05457162825e-34) /* kg m^2 / s */ +#define GSL_CONST_MKS_ASTRONOMICAL_UNIT (1.49597870691e11) /* m */ +#define GSL_CONST_MKS_LIGHT_YEAR (9.46053620707e15) /* m */ +#define GSL_CONST_MKS_PARSEC (3.08567758135e16) /* m */ +#define GSL_CONST_MKS_GRAV_ACCEL (9.80665e0) /* m / s^2 */ +#define GSL_CONST_MKS_ELECTRON_VOLT (1.602176487e-19) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_MASS_ELECTRON (9.10938188e-31) /* kg */ +#define GSL_CONST_MKS_MASS_MUON (1.88353109e-28) /* kg */ +#define GSL_CONST_MKS_MASS_PROTON (1.67262158e-27) /* kg */ +#define GSL_CONST_MKS_MASS_NEUTRON (1.67492716e-27) /* kg */ +#define GSL_CONST_MKS_RYDBERG (2.17987196968e-18) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_BOLTZMANN (1.3806504e-23) /* kg m^2 / K s^2 */ +#define GSL_CONST_MKS_MOLAR_GAS (8.314472e0) /* kg m^2 / K mol s^2 */ +#define GSL_CONST_MKS_STANDARD_GAS_VOLUME (2.2710981e-2) /* m^3 / mol */ +#define GSL_CONST_MKS_MINUTE (6e1) /* s */ +#define GSL_CONST_MKS_HOUR (3.6e3) /* s */ +#define GSL_CONST_MKS_DAY (8.64e4) /* s */ +#define GSL_CONST_MKS_WEEK (6.048e5) /* s */ +#define GSL_CONST_MKS_INCH (2.54e-2) /* m */ +#define GSL_CONST_MKS_FOOT (3.048e-1) /* m */ +#define GSL_CONST_MKS_YARD (9.144e-1) /* m */ +#define GSL_CONST_MKS_MILE (1.609344e3) /* m */ +#define GSL_CONST_MKS_NAUTICAL_MILE (1.852e3) /* m */ +#define GSL_CONST_MKS_FATHOM (1.8288e0) /* m */ +#define GSL_CONST_MKS_MIL (2.54e-5) /* m */ +#define GSL_CONST_MKS_POINT (3.52777777778e-4) /* m */ +#define GSL_CONST_MKS_TEXPOINT (3.51459803515e-4) /* m */ +#define GSL_CONST_MKS_MICRON (1e-6) /* m */ +#define GSL_CONST_MKS_ANGSTROM (1e-10) /* m */ +#define GSL_CONST_MKS_HECTARE (1e4) /* m^2 */ +#define GSL_CONST_MKS_ACRE (4.04685642241e3) /* m^2 */ +#define GSL_CONST_MKS_BARN (1e-28) /* m^2 */ +#define GSL_CONST_MKS_LITER (1e-3) /* m^3 */ +#define GSL_CONST_MKS_US_GALLON (3.78541178402e-3) /* m^3 */ +#define GSL_CONST_MKS_QUART (9.46352946004e-4) /* m^3 */ +#define GSL_CONST_MKS_PINT (4.73176473002e-4) /* m^3 */ +#define GSL_CONST_MKS_CUP (2.36588236501e-4) /* m^3 */ +#define GSL_CONST_MKS_FLUID_OUNCE (2.95735295626e-5) /* m^3 */ +#define GSL_CONST_MKS_TABLESPOON (1.47867647813e-5) /* m^3 */ +#define GSL_CONST_MKS_TEASPOON (4.92892159375e-6) /* m^3 */ +#define GSL_CONST_MKS_CANADIAN_GALLON (4.54609e-3) /* m^3 */ +#define GSL_CONST_MKS_UK_GALLON (4.546092e-3) /* m^3 */ +#define GSL_CONST_MKS_MILES_PER_HOUR (4.4704e-1) /* m / s */ +#define GSL_CONST_MKS_KILOMETERS_PER_HOUR (2.77777777778e-1) /* m / s */ +#define GSL_CONST_MKS_KNOT (5.14444444444e-1) /* m / s */ +#define GSL_CONST_MKS_POUND_MASS (4.5359237e-1) /* kg */ +#define GSL_CONST_MKS_OUNCE_MASS (2.8349523125e-2) /* kg */ +#define GSL_CONST_MKS_TON (9.0718474e2) /* kg */ +#define GSL_CONST_MKS_METRIC_TON (1e3) /* kg */ +#define GSL_CONST_MKS_UK_TON (1.0160469088e3) /* kg */ +#define GSL_CONST_MKS_TROY_OUNCE (3.1103475e-2) /* kg */ +#define GSL_CONST_MKS_CARAT (2e-4) /* kg */ +#define GSL_CONST_MKS_UNIFIED_ATOMIC_MASS (1.660538782e-27) /* kg */ +#define GSL_CONST_MKS_GRAM_FORCE (9.80665e-3) /* kg m / s^2 */ +#define GSL_CONST_MKS_POUND_FORCE (4.44822161526e0) /* kg m / s^2 */ +#define GSL_CONST_MKS_KILOPOUND_FORCE (4.44822161526e3) /* kg m / s^2 */ +#define GSL_CONST_MKS_POUNDAL (1.38255e-1) /* kg m / s^2 */ +#define GSL_CONST_MKS_CALORIE (4.1868e0) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_BTU (1.05505585262e3) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_THERM (1.05506e8) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_HORSEPOWER (7.457e2) /* kg m^2 / s^3 */ +#define GSL_CONST_MKS_BAR (1e5) /* kg / m s^2 */ +#define GSL_CONST_MKS_STD_ATMOSPHERE (1.01325e5) /* kg / m s^2 */ +#define GSL_CONST_MKS_TORR (1.33322368421e2) /* kg / m s^2 */ +#define GSL_CONST_MKS_METER_OF_MERCURY (1.33322368421e5) /* kg / m s^2 */ +#define GSL_CONST_MKS_INCH_OF_MERCURY (3.38638815789e3) /* kg / m s^2 */ +#define GSL_CONST_MKS_INCH_OF_WATER (2.490889e2) /* kg / m s^2 */ +#define GSL_CONST_MKS_PSI (6.89475729317e3) /* kg / m s^2 */ +#define GSL_CONST_MKS_POISE (1e-1) /* kg m^-1 s^-1 */ +#define GSL_CONST_MKS_STOKES (1e-4) /* m^2 / s */ +#define GSL_CONST_MKS_STILB (1e4) /* cd / m^2 */ +#define GSL_CONST_MKS_LUMEN (1e0) /* cd sr */ +#define GSL_CONST_MKS_LUX (1e0) /* cd sr / m^2 */ +#define GSL_CONST_MKS_PHOT (1e4) /* cd sr / m^2 */ +#define GSL_CONST_MKS_FOOTCANDLE (1.076e1) /* cd sr / m^2 */ +#define GSL_CONST_MKS_LAMBERT (1e4) /* cd sr / m^2 */ +#define GSL_CONST_MKS_FOOTLAMBERT (1.07639104e1) /* cd sr / m^2 */ +#define GSL_CONST_MKS_CURIE (3.7e10) /* 1 / s */ +#define GSL_CONST_MKS_ROENTGEN (2.58e-4) /* A s / kg */ +#define GSL_CONST_MKS_RAD (1e-2) /* m^2 / s^2 */ +#define GSL_CONST_MKS_SOLAR_MASS (1.98892e30) /* kg */ +#define GSL_CONST_MKS_BOHR_RADIUS (5.291772083e-11) /* m */ +#define GSL_CONST_MKS_NEWTON (1e0) /* kg m / s^2 */ +#define GSL_CONST_MKS_DYNE (1e-5) /* kg m / s^2 */ +#define GSL_CONST_MKS_JOULE (1e0) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_ERG (1e-7) /* kg m^2 / s^2 */ +#define GSL_CONST_MKS_STEFAN_BOLTZMANN_CONSTANT (5.67040047374e-8) /* kg / K^4 s^3 */ +#define GSL_CONST_MKS_THOMSON_CROSS_SECTION (6.65245893699e-29) /* m^2 */ +#define GSL_CONST_MKS_BOHR_MAGNETON (9.27400899e-24) /* A m^2 */ +#define GSL_CONST_MKS_NUCLEAR_MAGNETON (5.05078317e-27) /* A m^2 */ +#define GSL_CONST_MKS_ELECTRON_MAGNETIC_MOMENT (9.28476362e-24) /* A m^2 */ +#define GSL_CONST_MKS_PROTON_MAGNETIC_MOMENT (1.410606633e-26) /* A m^2 */ +#define GSL_CONST_MKS_FARADAY (9.64853429775e4) /* A s / mol */ +#define GSL_CONST_MKS_ELECTRON_CHARGE (1.602176487e-19) /* A s */ +#define GSL_CONST_MKS_VACUUM_PERMITTIVITY (8.854187817e-12) /* A^2 s^4 / kg m^3 */ +#define GSL_CONST_MKS_VACUUM_PERMEABILITY (1.25663706144e-6) /* kg m / A^2 s^2 */ +#define GSL_CONST_MKS_DEBYE (3.33564095198e-30) /* A s^2 / m^2 */ +#define GSL_CONST_MKS_GAUSS (1e-4) /* kg / A s^2 */ + +#endif /* __GSL_CONST_MKS__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const_mksa.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const_mksa.h new file mode 100644 index 0000000..5d91d1c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const_mksa.h @@ -0,0 +1,126 @@ +/* const/gsl_const_mksa.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST_MKSA__ +#define __GSL_CONST_MKSA__ + +#define GSL_CONST_MKSA_SPEED_OF_LIGHT (2.99792458e8) /* m / s */ +#define GSL_CONST_MKSA_GRAVITATIONAL_CONSTANT (6.673e-11) /* m^3 / kg s^2 */ +#define GSL_CONST_MKSA_PLANCKS_CONSTANT_H (6.62606896e-34) /* kg m^2 / s */ +#define GSL_CONST_MKSA_PLANCKS_CONSTANT_HBAR (1.05457162825e-34) /* kg m^2 / s */ +#define GSL_CONST_MKSA_ASTRONOMICAL_UNIT (1.49597870691e11) /* m */ +#define GSL_CONST_MKSA_LIGHT_YEAR (9.46053620707e15) /* m */ +#define GSL_CONST_MKSA_PARSEC (3.08567758135e16) /* m */ +#define GSL_CONST_MKSA_GRAV_ACCEL (9.80665e0) /* m / s^2 */ +#define GSL_CONST_MKSA_ELECTRON_VOLT (1.602176487e-19) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_MASS_ELECTRON (9.10938188e-31) /* kg */ +#define GSL_CONST_MKSA_MASS_MUON (1.88353109e-28) /* kg */ +#define GSL_CONST_MKSA_MASS_PROTON (1.67262158e-27) /* kg */ +#define GSL_CONST_MKSA_MASS_NEUTRON (1.67492716e-27) /* kg */ +#define GSL_CONST_MKSA_RYDBERG (2.17987196968e-18) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_BOLTZMANN (1.3806504e-23) /* kg m^2 / K s^2 */ +#define GSL_CONST_MKSA_MOLAR_GAS (8.314472e0) /* kg m^2 / K mol s^2 */ +#define GSL_CONST_MKSA_STANDARD_GAS_VOLUME (2.2710981e-2) /* m^3 / mol */ +#define GSL_CONST_MKSA_MINUTE (6e1) /* s */ +#define GSL_CONST_MKSA_HOUR (3.6e3) /* s */ +#define GSL_CONST_MKSA_DAY (8.64e4) /* s */ +#define GSL_CONST_MKSA_WEEK (6.048e5) /* s */ +#define GSL_CONST_MKSA_INCH (2.54e-2) /* m */ +#define GSL_CONST_MKSA_FOOT (3.048e-1) /* m */ +#define GSL_CONST_MKSA_YARD (9.144e-1) /* m */ +#define GSL_CONST_MKSA_MILE (1.609344e3) /* m */ +#define GSL_CONST_MKSA_NAUTICAL_MILE (1.852e3) /* m */ +#define GSL_CONST_MKSA_FATHOM (1.8288e0) /* m */ +#define GSL_CONST_MKSA_MIL (2.54e-5) /* m */ +#define GSL_CONST_MKSA_POINT (3.52777777778e-4) /* m */ +#define GSL_CONST_MKSA_TEXPOINT (3.51459803515e-4) /* m */ +#define GSL_CONST_MKSA_MICRON (1e-6) /* m */ +#define GSL_CONST_MKSA_ANGSTROM (1e-10) /* m */ +#define GSL_CONST_MKSA_HECTARE (1e4) /* m^2 */ +#define GSL_CONST_MKSA_ACRE (4.04685642241e3) /* m^2 */ +#define GSL_CONST_MKSA_BARN (1e-28) /* m^2 */ +#define GSL_CONST_MKSA_LITER (1e-3) /* m^3 */ +#define GSL_CONST_MKSA_US_GALLON (3.78541178402e-3) /* m^3 */ +#define GSL_CONST_MKSA_QUART (9.46352946004e-4) /* m^3 */ +#define GSL_CONST_MKSA_PINT (4.73176473002e-4) /* m^3 */ +#define GSL_CONST_MKSA_CUP (2.36588236501e-4) /* m^3 */ +#define GSL_CONST_MKSA_FLUID_OUNCE (2.95735295626e-5) /* m^3 */ +#define GSL_CONST_MKSA_TABLESPOON (1.47867647813e-5) /* m^3 */ +#define GSL_CONST_MKSA_TEASPOON (4.92892159375e-6) /* m^3 */ +#define GSL_CONST_MKSA_CANADIAN_GALLON (4.54609e-3) /* m^3 */ +#define GSL_CONST_MKSA_UK_GALLON (4.546092e-3) /* m^3 */ +#define GSL_CONST_MKSA_MILES_PER_HOUR (4.4704e-1) /* m / s */ +#define GSL_CONST_MKSA_KILOMETERS_PER_HOUR (2.77777777778e-1) /* m / s */ +#define GSL_CONST_MKSA_KNOT (5.14444444444e-1) /* m / s */ +#define GSL_CONST_MKSA_POUND_MASS (4.5359237e-1) /* kg */ +#define GSL_CONST_MKSA_OUNCE_MASS (2.8349523125e-2) /* kg */ +#define GSL_CONST_MKSA_TON (9.0718474e2) /* kg */ +#define GSL_CONST_MKSA_METRIC_TON (1e3) /* kg */ +#define GSL_CONST_MKSA_UK_TON (1.0160469088e3) /* kg */ +#define GSL_CONST_MKSA_TROY_OUNCE (3.1103475e-2) /* kg */ +#define GSL_CONST_MKSA_CARAT (2e-4) /* kg */ +#define GSL_CONST_MKSA_UNIFIED_ATOMIC_MASS (1.660538782e-27) /* kg */ +#define GSL_CONST_MKSA_GRAM_FORCE (9.80665e-3) /* kg m / s^2 */ +#define GSL_CONST_MKSA_POUND_FORCE (4.44822161526e0) /* kg m / s^2 */ +#define GSL_CONST_MKSA_KILOPOUND_FORCE (4.44822161526e3) /* kg m / s^2 */ +#define GSL_CONST_MKSA_POUNDAL (1.38255e-1) /* kg m / s^2 */ +#define GSL_CONST_MKSA_CALORIE (4.1868e0) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_BTU (1.05505585262e3) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_THERM (1.05506e8) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_HORSEPOWER (7.457e2) /* kg m^2 / s^3 */ +#define GSL_CONST_MKSA_BAR (1e5) /* kg / m s^2 */ +#define GSL_CONST_MKSA_STD_ATMOSPHERE (1.01325e5) /* kg / m s^2 */ +#define GSL_CONST_MKSA_TORR (1.33322368421e2) /* kg / m s^2 */ +#define GSL_CONST_MKSA_METER_OF_MERCURY (1.33322368421e5) /* kg / m s^2 */ +#define GSL_CONST_MKSA_INCH_OF_MERCURY (3.38638815789e3) /* kg / m s^2 */ +#define GSL_CONST_MKSA_INCH_OF_WATER (2.490889e2) /* kg / m s^2 */ +#define GSL_CONST_MKSA_PSI (6.89475729317e3) /* kg / m s^2 */ +#define GSL_CONST_MKSA_POISE (1e-1) /* kg m^-1 s^-1 */ +#define GSL_CONST_MKSA_STOKES (1e-4) /* m^2 / s */ +#define GSL_CONST_MKSA_STILB (1e4) /* cd / m^2 */ +#define GSL_CONST_MKSA_LUMEN (1e0) /* cd sr */ +#define GSL_CONST_MKSA_LUX (1e0) /* cd sr / m^2 */ +#define GSL_CONST_MKSA_PHOT (1e4) /* cd sr / m^2 */ +#define GSL_CONST_MKSA_FOOTCANDLE (1.076e1) /* cd sr / m^2 */ +#define GSL_CONST_MKSA_LAMBERT (1e4) /* cd sr / m^2 */ +#define GSL_CONST_MKSA_FOOTLAMBERT (1.07639104e1) /* cd sr / m^2 */ +#define GSL_CONST_MKSA_CURIE (3.7e10) /* 1 / s */ +#define GSL_CONST_MKSA_ROENTGEN (2.58e-4) /* A s / kg */ +#define GSL_CONST_MKSA_RAD (1e-2) /* m^2 / s^2 */ +#define GSL_CONST_MKSA_SOLAR_MASS (1.98892e30) /* kg */ +#define GSL_CONST_MKSA_BOHR_RADIUS (5.291772083e-11) /* m */ +#define GSL_CONST_MKSA_NEWTON (1e0) /* kg m / s^2 */ +#define GSL_CONST_MKSA_DYNE (1e-5) /* kg m / s^2 */ +#define GSL_CONST_MKSA_JOULE (1e0) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_ERG (1e-7) /* kg m^2 / s^2 */ +#define GSL_CONST_MKSA_STEFAN_BOLTZMANN_CONSTANT (5.67040047374e-8) /* kg / K^4 s^3 */ +#define GSL_CONST_MKSA_THOMSON_CROSS_SECTION (6.65245893699e-29) /* m^2 */ +#define GSL_CONST_MKSA_BOHR_MAGNETON (9.27400899e-24) /* A m^2 */ +#define GSL_CONST_MKSA_NUCLEAR_MAGNETON (5.05078317e-27) /* A m^2 */ +#define GSL_CONST_MKSA_ELECTRON_MAGNETIC_MOMENT (9.28476362e-24) /* A m^2 */ +#define GSL_CONST_MKSA_PROTON_MAGNETIC_MOMENT (1.410606633e-26) /* A m^2 */ +#define GSL_CONST_MKSA_FARADAY (9.64853429775e4) /* A s / mol */ +#define GSL_CONST_MKSA_ELECTRON_CHARGE (1.602176487e-19) /* A s */ +#define GSL_CONST_MKSA_VACUUM_PERMITTIVITY (8.854187817e-12) /* A^2 s^4 / kg m^3 */ +#define GSL_CONST_MKSA_VACUUM_PERMEABILITY (1.25663706144e-6) /* kg m / A^2 s^2 */ +#define GSL_CONST_MKSA_DEBYE (3.33564095198e-30) /* A s^2 / m^2 */ +#define GSL_CONST_MKSA_GAUSS (1e-4) /* kg / A s^2 */ + +#endif /* __GSL_CONST_MKSA__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_const_num.h b/ChaosDataPlayer/GSL/include/gsl/gsl_const_num.h new file mode 100644 index 0000000..385a660 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_const_num.h @@ -0,0 +1,43 @@ +/* const/gsl_const_num.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007, 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_CONST_NUM__ +#define __GSL_CONST_NUM__ + +#define GSL_CONST_NUM_FINE_STRUCTURE (7.297352533e-3) /* 1 */ +#define GSL_CONST_NUM_AVOGADRO (6.02214199e23) /* 1 / mol */ +#define GSL_CONST_NUM_YOTTA (1e24) /* 1 */ +#define GSL_CONST_NUM_ZETTA (1e21) /* 1 */ +#define GSL_CONST_NUM_EXA (1e18) /* 1 */ +#define GSL_CONST_NUM_PETA (1e15) /* 1 */ +#define GSL_CONST_NUM_TERA (1e12) /* 1 */ +#define GSL_CONST_NUM_GIGA (1e9) /* 1 */ +#define GSL_CONST_NUM_MEGA (1e6) /* 1 */ +#define GSL_CONST_NUM_KILO (1e3) /* 1 */ +#define GSL_CONST_NUM_MILLI (1e-3) /* 1 */ +#define GSL_CONST_NUM_MICRO (1e-6) /* 1 */ +#define GSL_CONST_NUM_NANO (1e-9) /* 1 */ +#define GSL_CONST_NUM_PICO (1e-12) /* 1 */ +#define GSL_CONST_NUM_FEMTO (1e-15) /* 1 */ +#define GSL_CONST_NUM_ATTO (1e-18) /* 1 */ +#define GSL_CONST_NUM_ZEPTO (1e-21) /* 1 */ +#define GSL_CONST_NUM_YOCTO (1e-24) /* 1 */ + +#endif /* __GSL_CONST_NUM__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_deriv.h b/ChaosDataPlayer/GSL/include/gsl/gsl_deriv.h new file mode 100644 index 0000000..7f4694f --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_deriv.h @@ -0,0 +1,50 @@ +/* deriv/gsl_deriv.h + * + * Copyright (C) 2000 David Morrison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DERIV_H__ +#define __GSL_DERIV_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_deriv_central (const gsl_function *f, + double x, double h, + double *result, double *abserr); + +int gsl_deriv_backward (const gsl_function *f, + double x, double h, + double *result, double *abserr); + +int gsl_deriv_forward (const gsl_function *f, + double x, double h, + double *result, double *abserr); + +__END_DECLS + +#endif /* __GSL_DERIV_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex.h b/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex.h new file mode 100644 index 0000000..cb4d088 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex.h @@ -0,0 +1,55 @@ +/* fft/gsl_dft_complex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DFT_COMPLEX_H__ +#define __GSL_DFT_COMPLEX_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_dft_complex_forward (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_backward (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_inverse (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_transform (const double data[], const size_t stride, const size_t n, + double result[], const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_DFT_COMPLEX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex_float.h new file mode 100644 index 0000000..c511ac0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_dft_complex_float.h @@ -0,0 +1,55 @@ +/* fft/gsl_dft_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DFT_COMPLEX_FLOAT_H__ +#define __GSL_DFT_COMPLEX_FLOAT_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_dft_complex_float_forward (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_backward (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_inverse (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_transform (const float data[], const size_t stride, const size_t n, + float result[], const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_DFT_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_dht.h b/ChaosDataPlayer/GSL/include/gsl/gsl_dht.h new file mode 100644 index 0000000..853e5da --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_dht.h @@ -0,0 +1,89 @@ +/* dht/gsl_dht.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman + */ +#ifndef __GSL_DHT_H__ +#define __GSL_DHT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +struct gsl_dht_struct { + size_t size; /* size of the sample arrays to be transformed */ + double nu; /* Bessel function order */ + double xmax; /* the upper limit to the x-sampling domain */ + double kmax; /* the upper limit to the k-sampling domain */ + double * j; /* array of computed J_nu zeros, j_{nu,s} = j[s] */ + double * Jjj; /* transform numerator, J_nu(j_i j_m / j_N) */ + double * J2; /* transform denominator, J_{nu+1}^2(j_m) */ +}; +typedef struct gsl_dht_struct gsl_dht; + + +/* Create a new transform object for a given size + * sampling array on the domain [0, xmax]. + */ +gsl_dht * gsl_dht_alloc(size_t size); +gsl_dht * gsl_dht_new(size_t size, double nu, double xmax); + +/* Recalculate a transform object for given values of nu, xmax. + * You cannot change the size of the object since the internal + * allocation is reused. + */ +int gsl_dht_init(gsl_dht * t, double nu, double xmax); + +/* The n'th computed x sample point for a given transform. + * 0 <= n <= size-1 + */ +double gsl_dht_x_sample(const gsl_dht * t, int n); + + +/* The n'th computed k sample point for a given transform. + * 0 <= n <= size-1 + */ +double gsl_dht_k_sample(const gsl_dht * t, int n); + + +/* Free a transform object. + */ +void gsl_dht_free(gsl_dht * t); + + +/* Perform a transform on a sampled array. + * f_in[0] ... f_in[size-1] and similarly for f_out[] + */ +int gsl_dht_apply(const gsl_dht * t, double * f_in, double * f_out); + + +__END_DECLS + +#endif /* __GSL_DHT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_diff.h b/ChaosDataPlayer/GSL/include/gsl/gsl_diff.h new file mode 100644 index 0000000..a145894 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_diff.h @@ -0,0 +1,52 @@ +/* diff/gsl_diff.h + * + * Copyright (C) 2000 David Morrison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DIFF_H__ +#define __GSL_DIFF_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +#ifndef GSL_DISABLE_DEPRECATED +int gsl_diff_central (const gsl_function *f, + double x, + double *result, double *abserr); + +int gsl_diff_backward (const gsl_function *f, + double x, + double *result, double *abserr); + +int gsl_diff_forward (const gsl_function *f, + double x, + double *result, double *abserr); +#endif + +__END_DECLS + +#endif /* __GSL_DIFF_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_eigen.h b/ChaosDataPlayer/GSL/include/gsl/gsl_eigen.h new file mode 100644 index 0000000..6de8dba --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_eigen.h @@ -0,0 +1,347 @@ +/* eigen/gsl_eigen.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007 Gerard Jungman, Brian Gough, Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_EIGEN_H__ +#define __GSL_EIGEN_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + size_t size; + double * d; + double * sd; +} gsl_eigen_symm_workspace; + +gsl_eigen_symm_workspace * gsl_eigen_symm_alloc (const size_t n); +void gsl_eigen_symm_free (gsl_eigen_symm_workspace * w); +int gsl_eigen_symm (gsl_matrix * A, gsl_vector * eval, gsl_eigen_symm_workspace * w); + +typedef struct { + size_t size; + double * d; + double * sd; + double * gc; + double * gs; +} gsl_eigen_symmv_workspace; + +gsl_eigen_symmv_workspace * gsl_eigen_symmv_alloc (const size_t n); +void gsl_eigen_symmv_free (gsl_eigen_symmv_workspace * w); +int gsl_eigen_symmv (gsl_matrix * A, gsl_vector * eval, gsl_matrix * evec, gsl_eigen_symmv_workspace * w); + +typedef struct { + size_t size; + double * d; + double * sd; + double * tau; +} gsl_eigen_herm_workspace; + +gsl_eigen_herm_workspace * gsl_eigen_herm_alloc (const size_t n); +void gsl_eigen_herm_free (gsl_eigen_herm_workspace * w); +int gsl_eigen_herm (gsl_matrix_complex * A, gsl_vector * eval, + gsl_eigen_herm_workspace * w); + +typedef struct { + size_t size; + double * d; + double * sd; + double * tau; + double * gc; + double * gs; +} gsl_eigen_hermv_workspace; + +gsl_eigen_hermv_workspace * gsl_eigen_hermv_alloc (const size_t n); +void gsl_eigen_hermv_free (gsl_eigen_hermv_workspace * w); +int gsl_eigen_hermv (gsl_matrix_complex * A, gsl_vector * eval, + gsl_matrix_complex * evec, + gsl_eigen_hermv_workspace * w); + +typedef struct { + size_t size; /* matrix size */ + size_t max_iterations; /* max iterations since last eigenvalue found */ + size_t n_iter; /* number of iterations since last eigenvalue found */ + size_t n_evals; /* number of eigenvalues found so far */ + + int compute_t; /* compute Schur form T = Z^t A Z */ + + gsl_matrix *H; /* pointer to Hessenberg matrix */ + gsl_matrix *Z; /* pointer to Schur vector matrix */ +} gsl_eigen_francis_workspace; + +gsl_eigen_francis_workspace * gsl_eigen_francis_alloc (void); +void gsl_eigen_francis_free (gsl_eigen_francis_workspace * w); +void gsl_eigen_francis_T (const int compute_t, + gsl_eigen_francis_workspace * w); +int gsl_eigen_francis (gsl_matrix * H, gsl_vector_complex * eval, + gsl_eigen_francis_workspace * w); +int gsl_eigen_francis_Z (gsl_matrix * H, gsl_vector_complex * eval, + gsl_matrix * Z, + gsl_eigen_francis_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + gsl_vector *diag; /* diagonal matrix elements from balancing */ + gsl_vector *tau; /* Householder coefficients */ + gsl_matrix *Z; /* pointer to Z matrix */ + int do_balance; /* perform balancing transformation? */ + size_t n_evals; /* number of eigenvalues found */ + + gsl_eigen_francis_workspace *francis_workspace_p; +} gsl_eigen_nonsymm_workspace; + +gsl_eigen_nonsymm_workspace * gsl_eigen_nonsymm_alloc (const size_t n); +void gsl_eigen_nonsymm_free (gsl_eigen_nonsymm_workspace * w); +void gsl_eigen_nonsymm_params (const int compute_t, const int balance, + gsl_eigen_nonsymm_workspace *w); +int gsl_eigen_nonsymm (gsl_matrix * A, gsl_vector_complex * eval, + gsl_eigen_nonsymm_workspace * w); +int gsl_eigen_nonsymm_Z (gsl_matrix * A, gsl_vector_complex * eval, + gsl_matrix * Z, gsl_eigen_nonsymm_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + gsl_vector *work; /* scratch workspace */ + gsl_vector *work2; /* scratch workspace */ + gsl_vector *work3; /* scratch workspace */ + + gsl_matrix *Z; /* pointer to Schur vectors */ + + gsl_eigen_nonsymm_workspace *nonsymm_workspace_p; +} gsl_eigen_nonsymmv_workspace; + +gsl_eigen_nonsymmv_workspace * gsl_eigen_nonsymmv_alloc (const size_t n); +void gsl_eigen_nonsymmv_free (gsl_eigen_nonsymmv_workspace * w); +void gsl_eigen_nonsymmv_params (const int balance, + gsl_eigen_nonsymmv_workspace *w); +int gsl_eigen_nonsymmv (gsl_matrix * A, gsl_vector_complex * eval, + gsl_matrix_complex * evec, + gsl_eigen_nonsymmv_workspace * w); +int gsl_eigen_nonsymmv_Z (gsl_matrix * A, gsl_vector_complex * eval, + gsl_matrix_complex * evec, gsl_matrix * Z, + gsl_eigen_nonsymmv_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + gsl_eigen_symm_workspace *symm_workspace_p; +} gsl_eigen_gensymm_workspace; + +gsl_eigen_gensymm_workspace * gsl_eigen_gensymm_alloc (const size_t n); +void gsl_eigen_gensymm_free (gsl_eigen_gensymm_workspace * w); +int gsl_eigen_gensymm (gsl_matrix * A, gsl_matrix * B, + gsl_vector * eval, gsl_eigen_gensymm_workspace * w); +int gsl_eigen_gensymm_standardize (gsl_matrix * A, const gsl_matrix * B); + +typedef struct { + size_t size; /* size of matrices */ + gsl_eigen_symmv_workspace *symmv_workspace_p; +} gsl_eigen_gensymmv_workspace; + +gsl_eigen_gensymmv_workspace * gsl_eigen_gensymmv_alloc (const size_t n); +void gsl_eigen_gensymmv_free (gsl_eigen_gensymmv_workspace * w); +int gsl_eigen_gensymmv (gsl_matrix * A, gsl_matrix * B, + gsl_vector * eval, gsl_matrix * evec, + gsl_eigen_gensymmv_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + gsl_eigen_herm_workspace *herm_workspace_p; +} gsl_eigen_genherm_workspace; + +gsl_eigen_genherm_workspace * gsl_eigen_genherm_alloc (const size_t n); +void gsl_eigen_genherm_free (gsl_eigen_genherm_workspace * w); +int gsl_eigen_genherm (gsl_matrix_complex * A, gsl_matrix_complex * B, + gsl_vector * eval, gsl_eigen_genherm_workspace * w); +int gsl_eigen_genherm_standardize (gsl_matrix_complex * A, + const gsl_matrix_complex * B); + +typedef struct { + size_t size; /* size of matrices */ + gsl_eigen_hermv_workspace *hermv_workspace_p; +} gsl_eigen_genhermv_workspace; + +gsl_eigen_genhermv_workspace * gsl_eigen_genhermv_alloc (const size_t n); +void gsl_eigen_genhermv_free (gsl_eigen_genhermv_workspace * w); +int gsl_eigen_genhermv (gsl_matrix_complex * A, gsl_matrix_complex * B, + gsl_vector * eval, gsl_matrix_complex * evec, + gsl_eigen_genhermv_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + gsl_vector *work; /* scratch workspace */ + + size_t n_evals; /* number of eigenvalues found */ + size_t max_iterations; /* maximum QZ iterations allowed */ + size_t n_iter; /* number of iterations since last eigenvalue found */ + double eshift; /* exceptional shift counter */ + + int needtop; /* need to compute top index? */ + + double atol; /* tolerance for splitting A matrix */ + double btol; /* tolerance for splitting B matrix */ + + double ascale; /* scaling factor for shifts */ + double bscale; /* scaling factor for shifts */ + + gsl_matrix *H; /* pointer to hessenberg matrix */ + gsl_matrix *R; /* pointer to upper triangular matrix */ + + int compute_s; /* compute generalized Schur form S */ + int compute_t; /* compute generalized Schur form T */ + + gsl_matrix *Q; /* pointer to left Schur vectors */ + gsl_matrix *Z; /* pointer to right Schur vectors */ +} gsl_eigen_gen_workspace; + +gsl_eigen_gen_workspace * gsl_eigen_gen_alloc (const size_t n); +void gsl_eigen_gen_free (gsl_eigen_gen_workspace * w); +void gsl_eigen_gen_params (const int compute_s, const int compute_t, + const int balance, gsl_eigen_gen_workspace * w); +int gsl_eigen_gen (gsl_matrix * A, gsl_matrix * B, + gsl_vector_complex * alpha, gsl_vector * beta, + gsl_eigen_gen_workspace * w); +int gsl_eigen_gen_QZ (gsl_matrix * A, gsl_matrix * B, + gsl_vector_complex * alpha, gsl_vector * beta, + gsl_matrix * Q, gsl_matrix * Z, + gsl_eigen_gen_workspace * w); + +typedef struct { + size_t size; /* size of matrices */ + + gsl_vector *work1; /* 1-norm of columns of A */ + gsl_vector *work2; /* 1-norm of columns of B */ + gsl_vector *work3; /* real part of eigenvector */ + gsl_vector *work4; /* imag part of eigenvector */ + gsl_vector *work5; /* real part of back-transformed eigenvector */ + gsl_vector *work6; /* imag part of back-transformed eigenvector */ + + gsl_matrix *Q; /* pointer to left Schur vectors */ + gsl_matrix *Z; /* pointer to right Schur vectors */ + + gsl_eigen_gen_workspace *gen_workspace_p; +} gsl_eigen_genv_workspace; + +gsl_eigen_genv_workspace * gsl_eigen_genv_alloc (const size_t n); +void gsl_eigen_genv_free (gsl_eigen_genv_workspace * w); +int gsl_eigen_genv (gsl_matrix * A, gsl_matrix * B, + gsl_vector_complex * alpha, gsl_vector * beta, + gsl_matrix_complex * evec, + gsl_eigen_genv_workspace * w); +int gsl_eigen_genv_QZ (gsl_matrix * A, gsl_matrix * B, + gsl_vector_complex * alpha, gsl_vector * beta, + gsl_matrix_complex * evec, + gsl_matrix * Q, gsl_matrix * Z, + gsl_eigen_genv_workspace * w); + + + +typedef enum { + GSL_EIGEN_SORT_VAL_ASC, + GSL_EIGEN_SORT_VAL_DESC, + GSL_EIGEN_SORT_ABS_ASC, + GSL_EIGEN_SORT_ABS_DESC +} +gsl_eigen_sort_t; + +/* Sort eigensystem results based on eigenvalues. + * Sorts in order of increasing value or increasing + * absolute value. + * + * exceptions: GSL_EBADLEN + */ + +int gsl_eigen_symmv_sort(gsl_vector * eval, gsl_matrix * evec, + gsl_eigen_sort_t sort_type); + +int gsl_eigen_hermv_sort(gsl_vector * eval, gsl_matrix_complex * evec, + gsl_eigen_sort_t sort_type); + +int gsl_eigen_nonsymmv_sort(gsl_vector_complex * eval, + gsl_matrix_complex * evec, + gsl_eigen_sort_t sort_type); + +int gsl_eigen_gensymmv_sort (gsl_vector * eval, gsl_matrix * evec, + gsl_eigen_sort_t sort_type); + +int gsl_eigen_genhermv_sort (gsl_vector * eval, gsl_matrix_complex * evec, + gsl_eigen_sort_t sort_type); + +int gsl_eigen_genv_sort (gsl_vector_complex * alpha, gsl_vector * beta, + gsl_matrix_complex * evec, + gsl_eigen_sort_t sort_type); + +/* Prototypes for the schur module */ + +int gsl_schur_gen_eigvals(const gsl_matrix *A, const gsl_matrix *B, + double *wr1, double *wr2, double *wi, + double *scale1, double *scale2); + +int gsl_schur_solve_equation(double ca, const gsl_matrix *A, double z, + double d1, double d2, const gsl_vector *b, + gsl_vector *x, double *s, double *xnorm, + double smin); + +int gsl_schur_solve_equation_z(double ca, const gsl_matrix *A, + gsl_complex *z, double d1, double d2, + const gsl_vector_complex *b, + gsl_vector_complex *x, double *s, + double *xnorm, double smin); + + +/* The following functions are obsolete: */ + +/* Eigensolve by Jacobi Method + * + * The data in the matrix input is destroyed. + * + * exceptions: + */ +int +gsl_eigen_jacobi(gsl_matrix * matrix, + gsl_vector * eval, + gsl_matrix * evec, + unsigned int max_rot, + unsigned int * nrot); + + +/* Invert by Jacobi Method + * + * exceptions: + */ +int +gsl_eigen_invert_jacobi(const gsl_matrix * matrix, + gsl_matrix * ainv, + unsigned int max_rot); + + + +__END_DECLS + +#endif /* __GSL_EIGEN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_errno.h b/ChaosDataPlayer/GSL/include/gsl/gsl_errno.h new file mode 100644 index 0000000..b8e99b4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_errno.h @@ -0,0 +1,154 @@ +/* err/gsl_errno.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_ERRNO_H__ +#define __GSL_ERRNO_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +enum { + GSL_SUCCESS = 0, + GSL_FAILURE = -1, + GSL_CONTINUE = -2, /* iteration has not converged */ + GSL_EDOM = 1, /* input domain error, e.g sqrt(-1) */ + GSL_ERANGE = 2, /* output range error, e.g. exp(1e100) */ + GSL_EFAULT = 3, /* invalid pointer */ + GSL_EINVAL = 4, /* invalid argument supplied by user */ + GSL_EFAILED = 5, /* generic failure */ + GSL_EFACTOR = 6, /* factorization failed */ + GSL_ESANITY = 7, /* sanity check failed - shouldn't happen */ + GSL_ENOMEM = 8, /* malloc failed */ + GSL_EBADFUNC = 9, /* problem with user-supplied function */ + GSL_ERUNAWAY = 10, /* iterative process is out of control */ + GSL_EMAXITER = 11, /* exceeded max number of iterations */ + GSL_EZERODIV = 12, /* tried to divide by zero */ + GSL_EBADTOL = 13, /* user specified an invalid tolerance */ + GSL_ETOL = 14, /* failed to reach the specified tolerance */ + GSL_EUNDRFLW = 15, /* underflow */ + GSL_EOVRFLW = 16, /* overflow */ + GSL_ELOSS = 17, /* loss of accuracy */ + GSL_EROUND = 18, /* failed because of roundoff error */ + GSL_EBADLEN = 19, /* matrix, vector lengths are not conformant */ + GSL_ENOTSQR = 20, /* matrix not square */ + GSL_ESING = 21, /* apparent singularity detected */ + GSL_EDIVERGE = 22, /* integral or series is divergent */ + GSL_EUNSUP = 23, /* requested feature is not supported by the hardware */ + GSL_EUNIMPL = 24, /* requested feature not (yet) implemented */ + GSL_ECACHE = 25, /* cache limit exceeded */ + GSL_ETABLE = 26, /* table limit exceeded */ + GSL_ENOPROG = 27, /* iteration is not making progress towards solution */ + GSL_ENOPROGJ = 28, /* jacobian evaluations are not improving the solution */ + GSL_ETOLF = 29, /* cannot reach the specified tolerance in F */ + GSL_ETOLX = 30, /* cannot reach the specified tolerance in X */ + GSL_ETOLG = 31, /* cannot reach the specified tolerance in gradient */ + GSL_EOF = 32 /* end of file */ +} ; + +void gsl_error (const char * reason, const char * file, int line, + int gsl_errno); + +void gsl_stream_printf (const char *label, const char *file, + int line, const char *reason); + +const char * gsl_strerror (const int gsl_errno); + +typedef void gsl_error_handler_t (const char * reason, const char * file, + int line, int gsl_errno); + +typedef void gsl_stream_handler_t (const char * label, const char * file, + int line, const char * reason); + +gsl_error_handler_t * +gsl_set_error_handler (gsl_error_handler_t * new_handler); + +gsl_error_handler_t * +gsl_set_error_handler_off (void); + +gsl_stream_handler_t * +gsl_set_stream_handler (gsl_stream_handler_t * new_handler); + +FILE * gsl_set_stream (FILE * new_stream); + +/* GSL_ERROR: call the error handler, and return the error code */ + +#define GSL_ERROR(reason, gsl_errno) \ + do { \ + gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ + return gsl_errno ; \ + } while (0) + +/* GSL_ERROR_VAL: call the error handler, and return the given value */ + +#define GSL_ERROR_VAL(reason, gsl_errno, value) \ + do { \ + gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ + return value ; \ + } while (0) + +/* GSL_ERROR_VOID: call the error handler, and then return + (for void functions which still need to generate an error) */ + +#define GSL_ERROR_VOID(reason, gsl_errno) \ + do { \ + gsl_error (reason, __FILE__, __LINE__, gsl_errno) ; \ + return ; \ + } while (0) + +/* GSL_ERROR_NULL suitable for out-of-memory conditions */ + +#define GSL_ERROR_NULL(reason, gsl_errno) GSL_ERROR_VAL(reason, gsl_errno, 0) + +/* Sometimes you have several status results returned from + * function calls and you want to combine them in some sensible + * way. You cannot produce a "total" status condition, but you can + * pick one from a set of conditions based on an implied hierarchy. + * + * In other words: + * you have: status_a, status_b, ... + * you want: status = (status_a if it is bad, or status_b if it is bad,...) + * + * In this example you consider status_a to be more important and + * it is checked first, followed by the others in the order specified. + * + * Here are some dumb macros to do this. + */ +#define GSL_ERROR_SELECT_2(a,b) ((a) != GSL_SUCCESS ? (a) : ((b) != GSL_SUCCESS ? (b) : GSL_SUCCESS)) +#define GSL_ERROR_SELECT_3(a,b,c) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_2(b,c)) +#define GSL_ERROR_SELECT_4(a,b,c,d) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_3(b,c,d)) +#define GSL_ERROR_SELECT_5(a,b,c,d,e) ((a) != GSL_SUCCESS ? (a) : GSL_ERROR_SELECT_4(b,c,d,e)) + +#define GSL_STATUS_UPDATE(sp, s) do { if ((s) != GSL_SUCCESS) *(sp) = (s);} while(0) + +__END_DECLS + +#endif /* __GSL_ERRNO_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft.h new file mode 100644 index 0000000..8870a88 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft.h @@ -0,0 +1,51 @@ +/* fft/gsl_fft.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_H__ +#define __GSL_FFT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum + { + gsl_fft_forward = -1, gsl_fft_backward = +1 + } +gsl_fft_direction; + +/* this gives the sign in the formula + + h(f) = \sum x(t) exp(+/- 2 pi i f t) + + where - is the forward transform direction and + the inverse direction */ + +__END_DECLS + +#endif /* __GSL_FFT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex.h new file mode 100644 index 0000000..c13f7ea --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex.h @@ -0,0 +1,136 @@ +/* fft/gsl_fft_complex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_COMPLEX_H__ +#define __GSL_FFT_COMPLEX_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Power of 2 routines */ + + +int gsl_fft_complex_radix2_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_transform (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +int gsl_fft_complex_radix2_dif_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_transform (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +/* Mixed Radix general-N routines */ + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_complex_wavetable; + +typedef struct +{ + size_t n; + double *scratch; +} +gsl_fft_complex_workspace; + + +gsl_fft_complex_wavetable *gsl_fft_complex_wavetable_alloc (size_t n); + +void gsl_fft_complex_wavetable_free (gsl_fft_complex_wavetable * wavetable); + +gsl_fft_complex_workspace *gsl_fft_complex_workspace_alloc (size_t n); + +void gsl_fft_complex_workspace_free (gsl_fft_complex_workspace * workspace); + +int gsl_fft_complex_memcpy (gsl_fft_complex_wavetable * dest, + gsl_fft_complex_wavetable * src); + + +int gsl_fft_complex_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_transform (gsl_complex_packed_array data, + const size_t stride, const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work, + const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_FFT_COMPLEX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex_float.h new file mode 100644 index 0000000..d3ff395 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_complex_float.h @@ -0,0 +1,139 @@ +/* fft/gsl_fft_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_COMPLEX_FLOAT_H__ +#define __GSL_FFT_COMPLEX_FLOAT_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Power of 2 routines */ + + +int gsl_fft_complex_float_radix2_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_transform (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +int gsl_fft_complex_float_radix2_dif_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_transform (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +/* Mixed Radix general-N routines */ + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_complex_wavetable_float; + +typedef struct +{ + size_t n; + float *scratch; +} +gsl_fft_complex_workspace_float; + + +gsl_fft_complex_wavetable_float *gsl_fft_complex_wavetable_float_alloc (size_t n); + +void gsl_fft_complex_wavetable_float_free (gsl_fft_complex_wavetable_float * wavetable); + +gsl_fft_complex_workspace_float *gsl_fft_complex_workspace_float_alloc (size_t n); + +void gsl_fft_complex_workspace_float_free (gsl_fft_complex_workspace_float * workspace); + + +int gsl_fft_complex_float_memcpy (gsl_fft_complex_wavetable_float * dest, + gsl_fft_complex_wavetable_float * src); + + +int gsl_fft_complex_float_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_transform (gsl_complex_packed_array_float data, + const size_t stride, const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work, + const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_FFT_COMPLEX_FLOAT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex.h new file mode 100644 index 0000000..6751e47 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex.h @@ -0,0 +1,86 @@ +/* fft/gsl_fft_halfcomplex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_HALFCOMPLEX_H__ +#define __GSL_FFT_HALFCOMPLEX_H__ + +#include + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_halfcomplex_radix2_backward (double data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_radix2_inverse (double data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_radix2_transform (double data[], const size_t stride, const size_t n); + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_halfcomplex_wavetable; + +gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc (size_t n); + +void +gsl_fft_halfcomplex_wavetable_free (gsl_fft_halfcomplex_wavetable * wavetable); + + +int gsl_fft_halfcomplex_backward (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int gsl_fft_halfcomplex_inverse (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int gsl_fft_halfcomplex_transform (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int +gsl_fft_halfcomplex_unpack (const double halfcomplex_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +int +gsl_fft_halfcomplex_radix2_unpack (const double halfcomplex_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_HALFCOMPLEX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex_float.h new file mode 100644 index 0000000..e318367 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_halfcomplex_float.h @@ -0,0 +1,86 @@ +/* fft/gsl_fft_halfcomplex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_HALFCOMPLEX_FLOAT_H__ +#define __GSL_FFT_HALFCOMPLEX_FLOAT_H__ + +#include + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_halfcomplex_float_radix2_backward (float data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_float_radix2_inverse (float data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_float_radix2_transform (float data[], const size_t stride, const size_t n); + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_halfcomplex_wavetable_float; + + +gsl_fft_halfcomplex_wavetable_float * gsl_fft_halfcomplex_wavetable_float_alloc (size_t n); + +void +gsl_fft_halfcomplex_wavetable_float_free (gsl_fft_halfcomplex_wavetable_float * wavetable); + +int gsl_fft_halfcomplex_float_backward (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int gsl_fft_halfcomplex_float_inverse (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int gsl_fft_halfcomplex_float_transform (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int +gsl_fft_halfcomplex_float_unpack (const float halfcomplex_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +int +gsl_fft_halfcomplex_float_radix2_unpack (const float halfcomplex_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_HALFCOMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real.h new file mode 100644 index 0000000..e07a604 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real.h @@ -0,0 +1,80 @@ +/* fft/gsl_fft_real.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_REAL_H__ +#define __GSL_FFT_REAL_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_real_radix2_transform (double data[], const size_t stride, const size_t n) ; + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_real_wavetable; + +typedef struct + { + size_t n; + double *scratch; + } +gsl_fft_real_workspace; + +gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc (size_t n); + +void gsl_fft_real_wavetable_free (gsl_fft_real_wavetable * wavetable); + +gsl_fft_real_workspace * gsl_fft_real_workspace_alloc (size_t n); + +void gsl_fft_real_workspace_free (gsl_fft_real_workspace * workspace); + + +int gsl_fft_real_transform (double data[], const size_t stride, const size_t n, + const gsl_fft_real_wavetable * wavetable, + gsl_fft_real_workspace * work); + + +int gsl_fft_real_unpack (const double real_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_REAL_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real_float.h new file mode 100644 index 0000000..7a7732f --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fft_real_float.h @@ -0,0 +1,79 @@ +/* fft/gsl_fft_real_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_REAL_FLOAT_H__ +#define __GSL_FFT_REAL_FLOAT_H__ + +#include + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_real_float_radix2_transform (float data[], const size_t stride, const size_t n) ; + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_real_wavetable_float; + +typedef struct + { + size_t n; + float *scratch; + } +gsl_fft_real_workspace_float; + +gsl_fft_real_wavetable_float * gsl_fft_real_wavetable_float_alloc (size_t n); + +void gsl_fft_real_wavetable_float_free (gsl_fft_real_wavetable_float * wavetable); + +gsl_fft_real_workspace_float * gsl_fft_real_workspace_float_alloc (size_t n); + +void gsl_fft_real_workspace_float_free (gsl_fft_real_workspace_float * workspace); + +int gsl_fft_real_float_transform (float data[], const size_t stride, const size_t n, + const gsl_fft_real_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + + +int gsl_fft_real_float_unpack (const float real_float_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_REAL_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_filter.h b/ChaosDataPlayer/GSL/include/gsl/gsl_filter.h new file mode 100644 index 0000000..7e902cd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_filter.h @@ -0,0 +1,108 @@ +/* filter/gsl_filter.h + * + * Copyright (C) 2018 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FILTER_H__ +#define __GSL_FILTER_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* end point handling methods */ +typedef enum +{ + GSL_FILTER_END_PADZERO = GSL_MOVSTAT_END_PADZERO, + GSL_FILTER_END_PADVALUE = GSL_MOVSTAT_END_PADVALUE, + GSL_FILTER_END_TRUNCATE = GSL_MOVSTAT_END_TRUNCATE +} gsl_filter_end_t; + +/* robust scale estimates */ +typedef enum +{ + GSL_FILTER_SCALE_MAD, /* median absolute deviation */ + GSL_FILTER_SCALE_IQR, /* interquartile range */ + GSL_FILTER_SCALE_SN, /* S_n scale statistic */ + GSL_FILTER_SCALE_QN /* Q_n scale statistic */ +} gsl_filter_scale_t; + +/* workspace for Gaussian filter */ +typedef struct +{ + size_t K; /* window size */ + double *kernel; /* Gaussian kernel, size K */ + gsl_movstat_workspace *movstat_workspace_p; +} gsl_filter_gaussian_workspace; + +gsl_filter_gaussian_workspace *gsl_filter_gaussian_alloc(const size_t K); +void gsl_filter_gaussian_free(gsl_filter_gaussian_workspace * w); +int gsl_filter_gaussian(const gsl_filter_end_t endtype, const double alpha, const size_t order, const gsl_vector * x, + gsl_vector * y, gsl_filter_gaussian_workspace * w); +int gsl_filter_gaussian_kernel(const double alpha, const size_t order, const int normalize, gsl_vector * kernel); + +/* workspace for standard median filter */ +typedef struct +{ + gsl_movstat_workspace *movstat_workspace_p; +} gsl_filter_median_workspace; + +gsl_filter_median_workspace *gsl_filter_median_alloc(const size_t K); +void gsl_filter_median_free(gsl_filter_median_workspace * w); +int gsl_filter_median(const gsl_filter_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_filter_median_workspace * w); + +/* workspace for recursive median filter */ +typedef struct +{ + size_t H; /* window half-length (K / 2) */ + size_t K; /* window size */ + void *state; /* workspace for min/max accumulator */ + double *window; /* array holding first window */ + const gsl_movstat_accum * minmaxacc; /* minimum/maximum accumulator */ + gsl_movstat_workspace *movstat_workspace_p; +} gsl_filter_rmedian_workspace; + +gsl_filter_rmedian_workspace *gsl_filter_rmedian_alloc(const size_t K); +void gsl_filter_rmedian_free(gsl_filter_rmedian_workspace * w); +int gsl_filter_rmedian(const gsl_filter_end_t, const gsl_vector * x, gsl_vector * y, gsl_filter_rmedian_workspace * w); + +typedef struct +{ + gsl_movstat_workspace *movstat_workspace_p; +} gsl_filter_impulse_workspace; + +gsl_filter_impulse_workspace *gsl_filter_impulse_alloc(const size_t K); +void gsl_filter_impulse_free(gsl_filter_impulse_workspace * w); +int gsl_filter_impulse(const gsl_filter_end_t endtype, const gsl_filter_scale_t scale_type, const double t, + const gsl_vector * x, gsl_vector * y, gsl_vector * xmedian, gsl_vector * xsigma, size_t * noutlier, + gsl_vector_int * ioutlier, gsl_filter_impulse_workspace * w); + +__END_DECLS + +#endif /* __GSL_FILTER_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_fit.h b/ChaosDataPlayer/GSL/include/gsl/gsl_fit.h new file mode 100644 index 0000000..de83a41 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_fit.h @@ -0,0 +1,85 @@ +/* fit/gsl_fit.h + * + * Copyright (C) 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FIT_H__ +#define __GSL_FIT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fit_linear (const double * x, const size_t xstride, + const double * y, const size_t ystride, + const size_t n, + double * c0, double * c1, + double * cov00, double * cov01, double * cov11, + double * sumsq); + + +int gsl_fit_wlinear (const double * x, const size_t xstride, + const double * w, const size_t wstride, + const double * y, const size_t ystride, + const size_t n, + double * c0, double * c1, + double * cov00, double * cov01, double * cov11, + double * chisq); + +int +gsl_fit_linear_est (const double x, + const double c0, const double c1, + const double cov00, const double cov01, const double cov11, + double *y, double *y_err); + + +int gsl_fit_mul (const double * x, const size_t xstride, + const double * y, const size_t ystride, + const size_t n, + double * c1, + double * cov11, + double * sumsq); + +int gsl_fit_wmul (const double * x, const size_t xstride, + const double * w, const size_t wstride, + const double * y, const size_t ystride, + const size_t n, + double * c1, + double * cov11, + double * sumsq); + + +int +gsl_fit_mul_est (const double x, + const double c1, + const double cov11, + double *y, double *y_err); + +__END_DECLS + +#endif /* __GSL_FIT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_heapsort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_heapsort.h new file mode 100644 index 0000000..213fae1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_heapsort.h @@ -0,0 +1,44 @@ +/* sort/gsl_heapsort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_HEAPSORT_H__ +#define __GSL_HEAPSORT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef int (*gsl_comparison_fn_t) (const void *, const void *); + +void gsl_heapsort (void * array, size_t count, size_t size, gsl_comparison_fn_t compare); +int gsl_heapsort_index (size_t * p, const void * array, size_t count, size_t size, gsl_comparison_fn_t compare); + +__END_DECLS + +#endif /* __GSL_HEAPSORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_histogram.h b/ChaosDataPlayer/GSL/include/gsl/gsl_histogram.h new file mode 100644 index 0000000..e8375c6 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_histogram.h @@ -0,0 +1,134 @@ +/* histogram/gsl_histogram.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_HISTOGRAM_H__ +#define __GSL_HISTOGRAM_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + size_t n ; + double * range ; + double * bin ; +} gsl_histogram ; + +typedef struct { + size_t n ; + double * range ; + double * sum ; +} gsl_histogram_pdf ; + +gsl_histogram * gsl_histogram_alloc (size_t n); + +gsl_histogram * gsl_histogram_calloc (size_t n); +gsl_histogram * gsl_histogram_calloc_uniform (const size_t n, const double xmin, const double xmax); +void gsl_histogram_free (gsl_histogram * h); +int gsl_histogram_increment (gsl_histogram * h, double x); +int gsl_histogram_accumulate (gsl_histogram * h, double x, double weight); +int gsl_histogram_find (const gsl_histogram * h, + const double x, size_t * i); + +double gsl_histogram_get (const gsl_histogram * h, size_t i); +int gsl_histogram_get_range (const gsl_histogram * h, size_t i, + double * lower, double * upper); + +double gsl_histogram_max (const gsl_histogram * h); +double gsl_histogram_min (const gsl_histogram * h); +size_t gsl_histogram_bins (const gsl_histogram * h); + +void gsl_histogram_reset (gsl_histogram * h); + +gsl_histogram * gsl_histogram_calloc_range(size_t n, double * range); + +int +gsl_histogram_set_ranges (gsl_histogram * h, const double range[], size_t size); +int +gsl_histogram_set_ranges_uniform (gsl_histogram * h, double xmin, double xmax); + + + +int +gsl_histogram_memcpy(gsl_histogram * dest, const gsl_histogram * source); + +gsl_histogram * +gsl_histogram_clone(const gsl_histogram * source); + +double gsl_histogram_max_val (const gsl_histogram * h); + +size_t gsl_histogram_max_bin (const gsl_histogram * h); + +double gsl_histogram_min_val (const gsl_histogram * h); + +size_t gsl_histogram_min_bin (const gsl_histogram * h); + +int +gsl_histogram_equal_bins_p(const gsl_histogram *h1, const gsl_histogram *h2); + +int +gsl_histogram_add(gsl_histogram *h1, const gsl_histogram *h2); + +int +gsl_histogram_sub(gsl_histogram *h1, const gsl_histogram *h2); + +int +gsl_histogram_mul(gsl_histogram *h1, const gsl_histogram *h2); + +int +gsl_histogram_div(gsl_histogram *h1, const gsl_histogram *h2); + +int +gsl_histogram_scale(gsl_histogram *h, double scale); + +int +gsl_histogram_shift (gsl_histogram * h, double shift); + + +double gsl_histogram_sigma (const gsl_histogram * h); + +double gsl_histogram_mean (const gsl_histogram * h); + +double gsl_histogram_sum (const gsl_histogram * h); + +int gsl_histogram_fwrite (FILE * stream, const gsl_histogram * h) ; +int gsl_histogram_fread (FILE * stream, gsl_histogram * h); +int gsl_histogram_fprintf (FILE * stream, const gsl_histogram * h, + const char * range_format, const char * bin_format); +int gsl_histogram_fscanf (FILE * stream, gsl_histogram * h); + +gsl_histogram_pdf * gsl_histogram_pdf_alloc (const size_t n); +int gsl_histogram_pdf_init (gsl_histogram_pdf * p, const gsl_histogram * h); +void gsl_histogram_pdf_free (gsl_histogram_pdf * p); +double gsl_histogram_pdf_sample (const gsl_histogram_pdf * p, double r); + +__END_DECLS + +#endif /* __GSL_HISTOGRAM_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_histogram2d.h b/ChaosDataPlayer/GSL/include/gsl/gsl_histogram2d.h new file mode 100644 index 0000000..90065ac --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_histogram2d.h @@ -0,0 +1,172 @@ +/* histogram/gsl_histogram2d.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_HISTOGRAM2D_H__ +#define __GSL_HISTOGRAM2D_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + size_t nx, ny ; + double * xrange ; + double * yrange ; + double * bin ; +} gsl_histogram2d ; + +typedef struct { + size_t nx, ny ; + double * xrange ; + double * yrange ; + double * sum ; +} gsl_histogram2d_pdf ; + +gsl_histogram2d * gsl_histogram2d_alloc (const size_t nx, const size_t ny); +gsl_histogram2d * gsl_histogram2d_calloc (const size_t nx, const size_t ny); +gsl_histogram2d * gsl_histogram2d_calloc_uniform (const size_t nx, const size_t ny, + const double xmin, const double xmax, + const double ymin, const double ymax); + +void gsl_histogram2d_free (gsl_histogram2d * h); + +int gsl_histogram2d_increment (gsl_histogram2d * h, double x, double y); +int gsl_histogram2d_accumulate (gsl_histogram2d * h, + double x, double y, double weight); +int gsl_histogram2d_find (const gsl_histogram2d * h, + const double x, const double y, size_t * i, size_t * j); + +double gsl_histogram2d_get (const gsl_histogram2d * h, const size_t i, const size_t j); +int gsl_histogram2d_get_xrange (const gsl_histogram2d * h, const size_t i, + double * xlower, double * xupper); +int gsl_histogram2d_get_yrange (const gsl_histogram2d * h, const size_t j, + double * ylower, double * yupper); + + +double gsl_histogram2d_xmax (const gsl_histogram2d * h); +double gsl_histogram2d_xmin (const gsl_histogram2d * h); +size_t gsl_histogram2d_nx (const gsl_histogram2d * h); + +double gsl_histogram2d_ymax (const gsl_histogram2d * h); +double gsl_histogram2d_ymin (const gsl_histogram2d * h); +size_t gsl_histogram2d_ny (const gsl_histogram2d * h); + +void gsl_histogram2d_reset (gsl_histogram2d * h); + +gsl_histogram2d * +gsl_histogram2d_calloc_range(size_t nx, size_t ny, + double *xrange, double *yrange); + +int +gsl_histogram2d_set_ranges_uniform (gsl_histogram2d * h, + double xmin, double xmax, + double ymin, double ymax); + +int +gsl_histogram2d_set_ranges (gsl_histogram2d * h, + const double xrange[], size_t xsize, + const double yrange[], size_t ysize); + +int +gsl_histogram2d_memcpy(gsl_histogram2d *dest, const gsl_histogram2d *source); + +gsl_histogram2d * +gsl_histogram2d_clone(const gsl_histogram2d * source); + +double +gsl_histogram2d_max_val(const gsl_histogram2d *h); + +void +gsl_histogram2d_max_bin (const gsl_histogram2d *h, size_t *i, size_t *j); + +double +gsl_histogram2d_min_val(const gsl_histogram2d *h); + +void +gsl_histogram2d_min_bin (const gsl_histogram2d *h, size_t *i, size_t *j); + +double +gsl_histogram2d_xmean (const gsl_histogram2d * h); + +double +gsl_histogram2d_ymean (const gsl_histogram2d * h); + +double +gsl_histogram2d_xsigma (const gsl_histogram2d * h); + +double +gsl_histogram2d_ysigma (const gsl_histogram2d * h); + +double +gsl_histogram2d_cov (const gsl_histogram2d * h); + +double +gsl_histogram2d_sum (const gsl_histogram2d *h); + +int +gsl_histogram2d_equal_bins_p(const gsl_histogram2d *h1, + const gsl_histogram2d *h2) ; + +int +gsl_histogram2d_add(gsl_histogram2d *h1, const gsl_histogram2d *h2); + +int +gsl_histogram2d_sub(gsl_histogram2d *h1, const gsl_histogram2d *h2); + +int +gsl_histogram2d_mul(gsl_histogram2d *h1, const gsl_histogram2d *h2); + +int +gsl_histogram2d_div(gsl_histogram2d *h1, const gsl_histogram2d *h2); + +int +gsl_histogram2d_scale(gsl_histogram2d *h, double scale); + +int +gsl_histogram2d_shift(gsl_histogram2d *h, double shift); + +int gsl_histogram2d_fwrite (FILE * stream, const gsl_histogram2d * h) ; +int gsl_histogram2d_fread (FILE * stream, gsl_histogram2d * h); +int gsl_histogram2d_fprintf (FILE * stream, const gsl_histogram2d * h, + const char * range_format, + const char * bin_format); +int gsl_histogram2d_fscanf (FILE * stream, gsl_histogram2d * h); + +gsl_histogram2d_pdf * gsl_histogram2d_pdf_alloc (const size_t nx, const size_t ny); +int gsl_histogram2d_pdf_init (gsl_histogram2d_pdf * p, const gsl_histogram2d * h); +void gsl_histogram2d_pdf_free (gsl_histogram2d_pdf * p); +int gsl_histogram2d_pdf_sample (const gsl_histogram2d_pdf * p, + double r1, double r2, + double * x, double * y); + +__END_DECLS + +#endif /* __GSL_HISTOGRAM2D_H__ */ + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_ieee_utils.h b/ChaosDataPlayer/GSL/include/gsl/gsl_ieee_utils.h new file mode 100644 index 0000000..a961220 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_ieee_utils.h @@ -0,0 +1,99 @@ +/* ieee-utils/gsl_ieee_utils.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_IEEE_UTILS_H__ +#define __GSL_IEEE_UTILS_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +enum { + GSL_IEEE_TYPE_NAN = 1, + GSL_IEEE_TYPE_INF = 2, + GSL_IEEE_TYPE_NORMAL = 3, + GSL_IEEE_TYPE_DENORMAL = 4, + GSL_IEEE_TYPE_ZERO = 5 +} ; + +typedef struct { + int sign ; + char mantissa[24] ; /* Actual bits are 0..22, element 23 is \0 */ + int exponent ; + int type ; +} gsl_ieee_float_rep ; + +typedef struct { + int sign ; + char mantissa[53] ; /* Actual bits are 0..51, element 52 is \0 */ + int exponent ; + int type ; +} gsl_ieee_double_rep ; + + +void gsl_ieee_printf_float (const float * x) ; +void gsl_ieee_printf_double (const double * x) ; + +void gsl_ieee_fprintf_float (FILE * stream, const float * x) ; +void gsl_ieee_fprintf_double (FILE * stream, const double * x) ; + +void gsl_ieee_float_to_rep (const float * x, gsl_ieee_float_rep * r) ; +void gsl_ieee_double_to_rep (const double * x, gsl_ieee_double_rep * r) ; + +enum { + GSL_IEEE_SINGLE_PRECISION = 1, + GSL_IEEE_DOUBLE_PRECISION = 2, + GSL_IEEE_EXTENDED_PRECISION = 3 +} ; + +enum { + GSL_IEEE_ROUND_TO_NEAREST = 1, + GSL_IEEE_ROUND_DOWN = 2, + GSL_IEEE_ROUND_UP = 3, + GSL_IEEE_ROUND_TO_ZERO = 4 +} ; + +enum { + GSL_IEEE_MASK_INVALID = 1, + GSL_IEEE_MASK_DENORMALIZED = 2, + GSL_IEEE_MASK_DIVISION_BY_ZERO = 4, + GSL_IEEE_MASK_OVERFLOW = 8, + GSL_IEEE_MASK_UNDERFLOW = 16, + GSL_IEEE_MASK_ALL = 31, + GSL_IEEE_TRAP_INEXACT = 32 +} ; + +void gsl_ieee_env_setup (void) ; +int gsl_ieee_read_mode_string (const char * description, int * precision, + int * rounding, int * exception_mask) ; +int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) ; + +__END_DECLS + +#endif /* __GSL_IEEE_UTILS_H__ */ + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_inline.h b/ChaosDataPlayer/GSL/include/gsl/gsl_inline.h new file mode 100644 index 0000000..f8fb9a0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_inline.h @@ -0,0 +1,67 @@ +/* gsl_inline.h + * + * Copyright (C) 2008, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_INLINE_H__ +#define __GSL_INLINE_H__ + +/* In recent versiions of GCC, the inline keyword has two different + forms: GNU and C99. + + In GNU mode we can use 'extern inline' to make inline functions + work like macros. The function is only inlined--it is never output + as a definition in an object file. + + In the new C99 mode 'extern inline' has a different meaning--it + causes the definition of the function to be output in each object + file where it is used. This will result in multiple-definition + errors on linking. The 'inline' keyword on its own (without + extern) has the same behavior as the original GNU 'extern inline'. + + The C99 style is the default with -std=c99 in GCC 4.3. + + This header file allows either form of inline to be used by + redefining the macros INLINE_DECL and INLINE_FUN. These are used + in the public header files as + + INLINE_DECL double gsl_foo (double x); + #ifdef HAVE_INLINE + INLINE_FUN double gsl_foo (double x) { return x+1.0; } ; + #endif + +*/ + +#ifdef HAVE_INLINE +# if defined(__GNUC_STDC_INLINE__) || defined(GSL_C99_INLINE) || defined(HAVE_C99_INLINE) +# define INLINE_DECL inline /* use C99 inline */ +# define INLINE_FUN inline +# else +# define INLINE_DECL /* use GNU extern inline */ +# define INLINE_FUN extern inline +# endif +#else +# define INLINE_DECL /* */ +#endif + +/* Range checking conditions in headers do not require any run-time + tests of the global variable gsl_check_range. They are enabled or + disabled in user code at compile time with GSL_RANGE_CHECK macro. + See also build.h. */ +#define GSL_RANGE_COND(x) (x) + +#endif /* __GSL_INLINE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_integration.h b/ChaosDataPlayer/GSL/include/gsl/gsl_integration.h new file mode 100644 index 0000000..b0c1b02 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_integration.h @@ -0,0 +1,390 @@ +/* integration/gsl_integration.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_INTEGRATION_H__ +#define __GSL_INTEGRATION_H__ +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Workspace for adaptive integrators */ + +typedef struct + { + size_t limit; + size_t size; + size_t nrmax; + size_t i; + size_t maximum_level; + double *alist; + double *blist; + double *rlist; + double *elist; + size_t *order; + size_t *level; + } +gsl_integration_workspace; + +gsl_integration_workspace * + gsl_integration_workspace_alloc (const size_t n); + +void + gsl_integration_workspace_free (gsl_integration_workspace * w); + + +/* Workspace for QAWS integrator */ + +typedef struct +{ + double alpha; + double beta; + int mu; + int nu; + double ri[25]; + double rj[25]; + double rg[25]; + double rh[25]; +} +gsl_integration_qaws_table; + +gsl_integration_qaws_table * +gsl_integration_qaws_table_alloc (double alpha, double beta, int mu, int nu); + +int +gsl_integration_qaws_table_set (gsl_integration_qaws_table * t, + double alpha, double beta, int mu, int nu); + +void +gsl_integration_qaws_table_free (gsl_integration_qaws_table * t); + +/* Workspace for QAWO integrator */ + +enum gsl_integration_qawo_enum { GSL_INTEG_COSINE, GSL_INTEG_SINE }; + +typedef struct +{ + size_t n; + double omega; + double L; + double par; + enum gsl_integration_qawo_enum sine; + double *chebmo; +} +gsl_integration_qawo_table; + +gsl_integration_qawo_table * +gsl_integration_qawo_table_alloc (double omega, double L, + enum gsl_integration_qawo_enum sine, + size_t n); + +int +gsl_integration_qawo_table_set (gsl_integration_qawo_table * t, + double omega, double L, + enum gsl_integration_qawo_enum sine); + +int +gsl_integration_qawo_table_set_length (gsl_integration_qawo_table * t, + double L); + +void +gsl_integration_qawo_table_free (gsl_integration_qawo_table * t); + + +/* Definition of an integration rule */ + +typedef void gsl_integration_rule (const gsl_function * f, + double a, double b, + double *result, double *abserr, + double *defabs, double *resabs); + +void gsl_integration_qk15 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qk21 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qk31 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qk41 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qk51 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qk61 (const gsl_function * f, double a, double b, + double *result, double *abserr, + double *resabs, double *resasc); + +void gsl_integration_qcheb (gsl_function * f, double a, double b, + double *cheb12, double *cheb24); + +/* The low-level integration rules in QUADPACK are identified by small + integers (1-6). We'll use symbolic constants to refer to them. */ + +enum + { + GSL_INTEG_GAUSS15 = 1, /* 15 point Gauss-Kronrod rule */ + GSL_INTEG_GAUSS21 = 2, /* 21 point Gauss-Kronrod rule */ + GSL_INTEG_GAUSS31 = 3, /* 31 point Gauss-Kronrod rule */ + GSL_INTEG_GAUSS41 = 4, /* 41 point Gauss-Kronrod rule */ + GSL_INTEG_GAUSS51 = 5, /* 51 point Gauss-Kronrod rule */ + GSL_INTEG_GAUSS61 = 6 /* 61 point Gauss-Kronrod rule */ + }; + +void +gsl_integration_qk (const int n, const double xgk[], + const double wg[], const double wgk[], + double fv1[], double fv2[], + const gsl_function *f, double a, double b, + double * result, double * abserr, + double * resabs, double * resasc); + + +int gsl_integration_qng (const gsl_function * f, + double a, double b, + double epsabs, double epsrel, + double *result, double *abserr, + size_t * neval); + +int gsl_integration_qag (const gsl_function * f, + double a, double b, + double epsabs, double epsrel, size_t limit, + int key, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qagi (gsl_function * f, + double epsabs, double epsrel, size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qagiu (gsl_function * f, + double a, + double epsabs, double epsrel, size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qagil (gsl_function * f, + double b, + double epsabs, double epsrel, size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + + +int gsl_integration_qags (const gsl_function * f, + double a, double b, + double epsabs, double epsrel, size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qagp (const gsl_function * f, + double *pts, size_t npts, + double epsabs, double epsrel, size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qawc (gsl_function *f, + const double a, const double b, const double c, + const double epsabs, const double epsrel, const size_t limit, + gsl_integration_workspace * workspace, + double * result, double * abserr); + +int gsl_integration_qaws (gsl_function * f, + const double a, const double b, + gsl_integration_qaws_table * t, + const double epsabs, const double epsrel, + const size_t limit, + gsl_integration_workspace * workspace, + double *result, double *abserr); + +int gsl_integration_qawo (gsl_function * f, + const double a, + const double epsabs, const double epsrel, + const size_t limit, + gsl_integration_workspace * workspace, + gsl_integration_qawo_table * wf, + double *result, double *abserr); + +int gsl_integration_qawf (gsl_function * f, + const double a, + const double epsabs, + const size_t limit, + gsl_integration_workspace * workspace, + gsl_integration_workspace * cycle_workspace, + gsl_integration_qawo_table * wf, + double *result, double *abserr); + +/* Workspace for fixed-order Gauss-Legendre integration */ + +typedef struct + { + size_t n; /* number of points */ + double *x; /* Gauss abscissae/points */ + double *w; /* Gauss weights for each abscissae */ + int precomputed; /* high precision abscissae/weights precomputed? */ + } +gsl_integration_glfixed_table; + + +gsl_integration_glfixed_table * gsl_integration_glfixed_table_alloc (size_t n); + +void gsl_integration_glfixed_table_free (gsl_integration_glfixed_table * t); + +/* Routine for fixed-order Gauss-Legendre integration */ + +double gsl_integration_glfixed (const gsl_function *f, + double a, + double b, + const gsl_integration_glfixed_table * t); + +/* Routine to retrieve the i-th Gauss-Legendre point and weight from t */ + +int gsl_integration_glfixed_point (double a, + double b, + size_t i, + double *xi, + double *wi, + const gsl_integration_glfixed_table * t); + + +/* Cquad integration - Pedro Gonnet */ + +/* Data of a single interval */ +typedef struct +{ + double a, b; + double c[64]; + double fx[33]; + double igral, err; + int depth, rdepth, ndiv; +} gsl_integration_cquad_ival; + + +/* The workspace is just a collection of intervals */ +typedef struct +{ + size_t size; + gsl_integration_cquad_ival *ivals; + size_t *heap; +} gsl_integration_cquad_workspace; + +gsl_integration_cquad_workspace * +gsl_integration_cquad_workspace_alloc (const size_t n); + +void +gsl_integration_cquad_workspace_free (gsl_integration_cquad_workspace * w); + +int +gsl_integration_cquad (const gsl_function * f, double a, double b, + double epsabs, double epsrel, + gsl_integration_cquad_workspace * ws, + double *result, double *abserr, size_t * nevals); + +/* Romberg integration workspace and routines */ + +typedef struct +{ + size_t n; /* maximum number of steps */ + double *work1; /* workspace for a row of R matrix, size n */ + double *work2; /* workspace for a row of R matrix, size n */ +} gsl_integration_romberg_workspace; + +gsl_integration_romberg_workspace *gsl_integration_romberg_alloc(const size_t n); +void gsl_integration_romberg_free(gsl_integration_romberg_workspace * w); +int gsl_integration_romberg(const gsl_function * f, const double a, const double b, + const double epsabs, const double epsrel, double * result, + size_t * neval, gsl_integration_romberg_workspace * w); + +/* IQPACK related structures and routines */ + +typedef struct +{ + double alpha; + double beta; + double a; + double b; + double zemu; + double shft; + double slp; + double al; + double be; +} gsl_integration_fixed_params; + +typedef struct +{ + int (*check)(const size_t n, const gsl_integration_fixed_params * params); + int (*init)(const size_t n, double * diag, double * subdiag, gsl_integration_fixed_params * params); +} gsl_integration_fixed_type; + +typedef struct +{ + size_t n; /* number of nodes/weights */ + double *weights; /* quadrature weights */ + double *x; /* quadrature nodes */ + double *diag; /* diagonal of Jacobi matrix */ + double *subdiag; /* subdiagonal of Jacobi matrix */ + const gsl_integration_fixed_type * type; +} gsl_integration_fixed_workspace; + +/* IQPACK integral types */ +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_legendre; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_chebyshev; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_gegenbauer; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_jacobi; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_laguerre; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_hermite; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_exponential; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_rational; +GSL_VAR const gsl_integration_fixed_type * gsl_integration_fixed_chebyshev2; + +gsl_integration_fixed_workspace * +gsl_integration_fixed_alloc(const gsl_integration_fixed_type * type, const size_t n, + const double a, const double b, const double alpha, const double beta); + +void gsl_integration_fixed_free(gsl_integration_fixed_workspace * w); + +size_t gsl_integration_fixed_n(const gsl_integration_fixed_workspace * w); + +double *gsl_integration_fixed_nodes(const gsl_integration_fixed_workspace * w); + +double *gsl_integration_fixed_weights(const gsl_integration_fixed_workspace * w); + +int gsl_integration_fixed(const gsl_function * func, double * result, + const gsl_integration_fixed_workspace * w); + +__END_DECLS + +#endif /* __GSL_INTEGRATION_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_interp.h b/ChaosDataPlayer/GSL/include/gsl/gsl_interp.h new file mode 100644 index 0000000..8321224 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_interp.h @@ -0,0 +1,225 @@ +/* interpolation/gsl_interp.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman + */ +#ifndef __GSL_INTERP_H__ +#define __GSL_INTERP_H__ +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* evaluation accelerator */ +typedef struct { + size_t cache; /* cache of index */ + size_t miss_count; /* keep statistics */ + size_t hit_count; +} +gsl_interp_accel; + + +/* interpolation object type */ +typedef struct { + const char * name; + unsigned int min_size; + void * (*alloc) (size_t size); + int (*init) (void *, const double xa[], const double ya[], size_t size); + int (*eval) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y); + int (*eval_deriv) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_p); + int (*eval_deriv2) (const void *, const double xa[], const double ya[], size_t size, double x, gsl_interp_accel *, double * y_pp); + int (*eval_integ) (const void *, const double xa[], const double ya[], size_t size, gsl_interp_accel *, double a, double b, double * result); + void (*free) (void *); + +} gsl_interp_type; + + +/* general interpolation object */ +typedef struct { + const gsl_interp_type * type; + double xmin; + double xmax; + size_t size; + void * state; +} gsl_interp; + + +/* available types */ +GSL_VAR const gsl_interp_type * gsl_interp_linear; +GSL_VAR const gsl_interp_type * gsl_interp_polynomial; +GSL_VAR const gsl_interp_type * gsl_interp_cspline; +GSL_VAR const gsl_interp_type * gsl_interp_cspline_periodic; +GSL_VAR const gsl_interp_type * gsl_interp_akima; +GSL_VAR const gsl_interp_type * gsl_interp_akima_periodic; +GSL_VAR const gsl_interp_type * gsl_interp_steffen; + +gsl_interp_accel * +gsl_interp_accel_alloc(void); + +int +gsl_interp_accel_reset (gsl_interp_accel * a); + +void +gsl_interp_accel_free(gsl_interp_accel * a); + +gsl_interp * +gsl_interp_alloc(const gsl_interp_type * T, size_t n); + +int +gsl_interp_init(gsl_interp * obj, const double xa[], const double ya[], size_t size); + +const char * gsl_interp_name(const gsl_interp * interp); +unsigned int gsl_interp_min_size(const gsl_interp * interp); +unsigned int gsl_interp_type_min_size(const gsl_interp_type * T); + + +int +gsl_interp_eval_e(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a, double * y); + +double +gsl_interp_eval(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a); + +int +gsl_interp_eval_deriv_e(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a, + double * d); + +double +gsl_interp_eval_deriv(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a); + +int +gsl_interp_eval_deriv2_e(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a, + double * d2); + +double +gsl_interp_eval_deriv2(const gsl_interp * obj, + const double xa[], const double ya[], double x, + gsl_interp_accel * a); + +int +gsl_interp_eval_integ_e(const gsl_interp * obj, + const double xa[], const double ya[], + double a, double b, + gsl_interp_accel * acc, + double * result); + +double +gsl_interp_eval_integ(const gsl_interp * obj, + const double xa[], const double ya[], + double a, double b, + gsl_interp_accel * acc); + +void +gsl_interp_free(gsl_interp * interp); + +INLINE_DECL size_t +gsl_interp_bsearch(const double x_array[], double x, + size_t index_lo, size_t index_hi); + +#ifdef HAVE_INLINE + +/* Perform a binary search of an array of values. + * + * The parameters index_lo and index_hi provide an initial bracket, + * and it is assumed that index_lo < index_hi. The resulting index + * is guaranteed to be strictly less than index_hi and greater than + * or equal to index_lo, so that the implicit bracket [index, index+1] + * always corresponds to a region within the implicit value range of + * the value array. + * + * Note that this means the relationship of 'x' to x_array[index] + * and x_array[index+1] depends on the result region, i.e. the + * behaviour at the boundaries may not correspond to what you + * expect. We have the following complete specification of the + * behaviour. + * Suppose the input is x_array[] = { x0, x1, ..., xN } + * if ( x == x0 ) then index == 0 + * if ( x > x0 && x <= x1 ) then index == 0, and sim. for other interior pts + * if ( x == xN ) then index == N-1 + * if ( x > xN ) then index == N-1 + * if ( x < x0 ) then index == 0 + */ + +INLINE_FUN size_t +gsl_interp_bsearch(const double x_array[], double x, + size_t index_lo, size_t index_hi) +{ + size_t ilo = index_lo; + size_t ihi = index_hi; + while(ihi > ilo + 1) { + size_t i = (ihi + ilo)/2; + if(x_array[i] > x) + ihi = i; + else + ilo = i; + } + + return ilo; +} +#endif + +INLINE_DECL size_t +gsl_interp_accel_find(gsl_interp_accel * a, const double x_array[], size_t size, double x); + +#ifdef HAVE_INLINE +INLINE_FUN size_t +gsl_interp_accel_find(gsl_interp_accel * a, const double xa[], size_t len, double x) +{ + size_t x_index = a->cache; + + if(x < xa[x_index]) { + a->miss_count++; + a->cache = gsl_interp_bsearch(xa, x, 0, x_index); + } + else if(x >= xa[x_index + 1]) { + a->miss_count++; + a->cache = gsl_interp_bsearch(xa, x, x_index, len-1); + } + else { + a->hit_count++; + } + + return a->cache; +} +#endif /* HAVE_INLINE */ + + +__END_DECLS + +#endif /* __GSL_INTERP_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_interp2d.h b/ChaosDataPlayer/GSL/include/gsl/gsl_interp2d.h new file mode 100644 index 0000000..e35fd81 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_interp2d.h @@ -0,0 +1,174 @@ +/* interpolation/gsl_interp2d.h + * + * Copyright 2012 David Zaslavsky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_INTERP2D_H__ +#define __GSL_INTERP2D_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + const char* name; + unsigned int min_size; + void * (*alloc)(size_t xsize, size_t ysize); + int (*init)(void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize); + int (*eval)(const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z); + int (*eval_deriv_x) (const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_p); + int (*eval_deriv_y) (const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_p); + int (*eval_deriv_xx) (const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp); + int (*eval_deriv_xy) (const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp); + int (*eval_deriv_yy) (const void *, const double xa[], const double ya[], const double za[], size_t xsize, size_t ysize, double x, double y, gsl_interp_accel*, gsl_interp_accel*, double* z_pp); + void (*free)(void *); +} gsl_interp2d_type; + +typedef struct { + const gsl_interp2d_type * type; /* interpolation type */ + double xmin; /* minimum value of x for which data have been provided */ + double xmax; /* maximum value of x for which data have been provided */ + double ymin; /* minimum value of y for which data have been provided */ + double ymax; /* maximum value of y for which data have been provided */ + size_t xsize; /* number of x values provided */ + size_t ysize; /* number of y values provided */ + void * state; /* internal state object specific to the interpolation type */ +} gsl_interp2d; + +/* available types */ +GSL_VAR const gsl_interp2d_type * gsl_interp2d_bilinear; +GSL_VAR const gsl_interp2d_type * gsl_interp2d_bicubic; + +gsl_interp2d * gsl_interp2d_alloc(const gsl_interp2d_type * T, const size_t xsize, + const size_t ysize); + +const char * gsl_interp2d_name(const gsl_interp2d * interp); +size_t gsl_interp2d_min_size(const gsl_interp2d * interp); +size_t gsl_interp2d_type_min_size(const gsl_interp2d_type * T); +int gsl_interp2d_set(const gsl_interp2d * interp, double zarr[], + const size_t i, const size_t j, const double z); +double gsl_interp2d_get(const gsl_interp2d * interp, const double zarr[], + const size_t i, const size_t j); +size_t gsl_interp2d_idx(const gsl_interp2d * interp, + const size_t i, const size_t j); +int gsl_interp2d_init(gsl_interp2d * interp, const double xa[], const double ya[], + const double za[], const size_t xsize, const size_t ysize); +void gsl_interp2d_free(gsl_interp2d * interp); + +double gsl_interp2d_eval(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], const double x, + const double y, gsl_interp_accel * xa, gsl_interp_accel * ya); + +double gsl_interp2d_eval_extrap(const gsl_interp2d * interp, + const double xarr[], const double yarr[], + const double zarr[], const double x, + const double y, gsl_interp_accel * xa, + gsl_interp_accel * ya); + +int gsl_interp2d_eval_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_interp2d_eval_e_extrap(const gsl_interp2d * interp, + const double xarr[], + const double yarr[], + const double zarr[], + const double x, + const double y, + gsl_interp_accel * xa, + gsl_interp_accel * ya, + double * z); + +#endif /* !GSL_DISABLE_DEPRECATED */ + +int gsl_interp2d_eval_extrap_e(const gsl_interp2d * interp, + const double xarr[], + const double yarr[], + const double zarr[], + const double x, + const double y, + gsl_interp_accel * xa, + gsl_interp_accel * ya, + double * z); + +double gsl_interp2d_eval_deriv_x(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, gsl_interp_accel * xa, + gsl_interp_accel * ya); + +int gsl_interp2d_eval_deriv_x_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya, double * z); + +double gsl_interp2d_eval_deriv_y(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_interp2d_eval_deriv_y_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya, double * z); + +double gsl_interp2d_eval_deriv_xx(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya); + +int gsl_interp2d_eval_deriv_xx_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya, double * z); + +double gsl_interp2d_eval_deriv_yy(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya); + +int gsl_interp2d_eval_deriv_yy_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya, double * z); + +double gsl_interp2d_eval_deriv_xy(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya); + +int gsl_interp2d_eval_deriv_xy_e(const gsl_interp2d * interp, const double xarr[], + const double yarr[], const double zarr[], + const double x, const double y, + gsl_interp_accel * xa, gsl_interp_accel * ya, double * z); + + +__END_DECLS + +#endif /* __GSL_INTERP2D_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_linalg.h b/ChaosDataPlayer/GSL/include/gsl/gsl_linalg.h new file mode 100644 index 0000000..d3ec40c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_linalg.h @@ -0,0 +1,925 @@ +/* linalg/gsl_linalg.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2006, 2007, 2019 Gerard Jungman, Brian Gough, Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_LINALG_H__ +#define __GSL_LINALG_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS /* empty */ +#define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum + { + GSL_LINALG_MOD_NONE = 0, + GSL_LINALG_MOD_TRANSPOSE = 1, + GSL_LINALG_MOD_CONJUGATE = 2 + } +gsl_linalg_matrix_mod_t; + +/* Note: You can now use the gsl_blas_dgemm function instead of matmult */ + +/* Simple implementation of matrix multiply. + * Calculates C = A.B + * + * exceptions: GSL_EBADLEN + */ +int gsl_linalg_matmult (const gsl_matrix * A, + const gsl_matrix * B, + gsl_matrix * C); + + +/* Simple implementation of matrix multiply. + * Allows transposition of either matrix, so it + * can compute A.B or Trans(A).B or A.Trans(B) or Trans(A).Trans(B) + * + * exceptions: GSL_EBADLEN + */ +int gsl_linalg_matmult_mod (const gsl_matrix * A, + gsl_linalg_matrix_mod_t modA, + const gsl_matrix * B, + gsl_linalg_matrix_mod_t modB, + gsl_matrix * C); + +/* Calculate the matrix exponential by the scaling and + * squaring method described in Moler + Van Loan, + * SIAM Rev 20, 801 (1978). The mode argument allows + * choosing an optimal strategy, from the table + * given in the paper, for a given precision. + * + * exceptions: GSL_ENOTSQR, GSL_EBADLEN + */ +int gsl_linalg_exponential_ss( + const gsl_matrix * A, + gsl_matrix * eA, + gsl_mode_t mode + ); + + +/* Householder Transformations */ + +double gsl_linalg_householder_transform (gsl_vector * v); +double gsl_linalg_householder_transform2 (double * alpha, gsl_vector * v); +gsl_complex gsl_linalg_complex_householder_transform (gsl_vector_complex * v); + +int gsl_linalg_householder_hm (double tau, + const gsl_vector * v, + gsl_matrix * A); + +int gsl_linalg_householder_mh (double tau, + const gsl_vector * v, + gsl_matrix * A); + +int gsl_linalg_householder_hv (double tau, + const gsl_vector * v, + gsl_vector * w); + +int gsl_linalg_householder_left(const double tau, + const gsl_vector * v, + gsl_matrix * A, + gsl_vector * work); + +int gsl_linalg_householder_right(const double tau, + const gsl_vector * v, + gsl_matrix * A, + gsl_vector * work); + +int gsl_linalg_householder_hm1 (double tau, + gsl_matrix * A); + +int gsl_linalg_complex_householder_hm (gsl_complex tau, + const gsl_vector_complex * v, + gsl_matrix_complex * A); + +int gsl_linalg_complex_householder_mh (gsl_complex tau, + const gsl_vector_complex * v, + gsl_matrix_complex * A); + +int gsl_linalg_complex_householder_hv (gsl_complex tau, + const gsl_vector_complex * v, + gsl_vector_complex * w); + +int gsl_linalg_complex_householder_left (const gsl_complex tau, + const gsl_vector_complex * v, + gsl_matrix_complex * A, + gsl_vector_complex * work); + +/* Hessenberg reduction */ + +int gsl_linalg_hessenberg_decomp(gsl_matrix *A, gsl_vector *tau); +int gsl_linalg_hessenberg_unpack(gsl_matrix * H, gsl_vector * tau, + gsl_matrix * U); +int gsl_linalg_hessenberg_unpack_accum(gsl_matrix * H, gsl_vector * tau, + gsl_matrix * U); +int gsl_linalg_hessenberg_set_zero(gsl_matrix * H); +int gsl_linalg_hessenberg_submatrix(gsl_matrix *M, gsl_matrix *A, + size_t top, gsl_vector *tau); + +/* Hessenberg-Triangular reduction */ + +int gsl_linalg_hesstri_decomp(gsl_matrix * A, gsl_matrix * B, + gsl_matrix * U, gsl_matrix * V, + gsl_vector * work); + +/* Singular Value Decomposition + + * exceptions: + */ + +int +gsl_linalg_SV_decomp (gsl_matrix * A, + gsl_matrix * V, + gsl_vector * S, + gsl_vector * work); + +int +gsl_linalg_SV_decomp_mod (gsl_matrix * A, + gsl_matrix * X, + gsl_matrix * V, + gsl_vector * S, + gsl_vector * work); + +int gsl_linalg_SV_decomp_jacobi (gsl_matrix * A, + gsl_matrix * Q, + gsl_vector * S); + +int +gsl_linalg_SV_solve (const gsl_matrix * U, + const gsl_matrix * Q, + const gsl_vector * S, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_SV_leverage(const gsl_matrix *U, gsl_vector *h); + + +/* LU Decomposition, Gaussian elimination with partial pivoting + */ + +int gsl_linalg_LU_decomp (gsl_matrix * A, gsl_permutation * p, int *signum); + +int gsl_linalg_LU_solve (const gsl_matrix * LU, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_LU_svx (const gsl_matrix * LU, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_LU_refine (const gsl_matrix * A, + const gsl_matrix * LU, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x, + gsl_vector * work); + +int gsl_linalg_LU_invert (const gsl_matrix * LU, + const gsl_permutation * p, + gsl_matrix * inverse); +int gsl_linalg_LU_invx (gsl_matrix * LU, const gsl_permutation * p); + +double gsl_linalg_LU_det (gsl_matrix * LU, int signum); +double gsl_linalg_LU_lndet (gsl_matrix * LU); +int gsl_linalg_LU_sgndet (gsl_matrix * lu, int signum); + +/* Banded LU decomposition */ + +int gsl_linalg_LU_band_decomp (const size_t M, const size_t lb, const size_t ub, gsl_matrix * AB, gsl_vector_uint * piv); + +int gsl_linalg_LU_band_solve (const size_t lb, const size_t ub, const gsl_matrix * LUB, + const gsl_vector_uint * piv, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_LU_band_svx (const size_t lb, const size_t ub, const gsl_matrix * LUB, + const gsl_vector_uint * piv, gsl_vector * x); + +int gsl_linalg_LU_band_unpack (const size_t M, const size_t lb, const size_t ub, const gsl_matrix * LUB, + const gsl_vector_uint * piv, gsl_matrix * L, gsl_matrix * U); + +/* Complex LU Decomposition */ + +int gsl_linalg_complex_LU_decomp (gsl_matrix_complex * A, + gsl_permutation * p, + int *signum); + +int gsl_linalg_complex_LU_solve (const gsl_matrix_complex * LU, + const gsl_permutation * p, + const gsl_vector_complex * b, + gsl_vector_complex * x); + +int gsl_linalg_complex_LU_svx (const gsl_matrix_complex * LU, + const gsl_permutation * p, + gsl_vector_complex * x); + +int gsl_linalg_complex_LU_refine (const gsl_matrix_complex * A, + const gsl_matrix_complex * LU, + const gsl_permutation * p, + const gsl_vector_complex * b, + gsl_vector_complex * x, + gsl_vector_complex * work); + +int gsl_linalg_complex_LU_invert (const gsl_matrix_complex * LU, + const gsl_permutation * p, + gsl_matrix_complex * inverse); +int gsl_linalg_complex_LU_invx (gsl_matrix_complex * LU, const gsl_permutation * p); + +gsl_complex gsl_linalg_complex_LU_det (gsl_matrix_complex * LU, + int signum); + +double gsl_linalg_complex_LU_lndet (gsl_matrix_complex * LU); + +gsl_complex gsl_linalg_complex_LU_sgndet (gsl_matrix_complex * LU, + int signum); + +/* QR decomposition */ + +int gsl_linalg_QR_decomp (gsl_matrix * A, gsl_vector * tau); + +int gsl_linalg_QR_decomp_old (gsl_matrix * A, gsl_vector * tau); + +int gsl_linalg_QR_decomp_r (gsl_matrix * A, gsl_matrix * T); + +int gsl_linalg_QR_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_QR_solve_r (const gsl_matrix * QR, const gsl_matrix * T, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_QR_svx (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * x); + +int gsl_linalg_QR_lssolve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, + gsl_vector * x, gsl_vector * residual); + +int gsl_linalg_QR_lssolve_r (const gsl_matrix * QR, const gsl_matrix * T, const gsl_vector * b, + gsl_vector * x, gsl_vector * work); + +int gsl_linalg_QR_QRsolve (gsl_matrix * Q, gsl_matrix * R, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_QR_Rsolve (const gsl_matrix * QR, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_QR_Rsvx (const gsl_matrix * QR, gsl_vector * x); + +int gsl_linalg_QR_update (gsl_matrix * Q, gsl_matrix * R, gsl_vector * w, const gsl_vector * v); + +int gsl_linalg_QR_QTvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v); + +int gsl_linalg_QR_QTvec_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_vector * b, gsl_vector * work); + +int gsl_linalg_QR_Qvec (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v); + +int gsl_linalg_QR_QTmat (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * A); + +int gsl_linalg_QR_QTmat_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_matrix * B, gsl_matrix * work); + +int gsl_linalg_QR_matQ (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * A); + +int gsl_linalg_QR_unpack (const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * R); + +int gsl_linalg_QR_unpack_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_matrix * Q, gsl_matrix * R); + +int gsl_linalg_R_solve (const gsl_matrix * R, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_R_svx (const gsl_matrix * R, gsl_vector * x); + +int gsl_linalg_QR_rcond(const gsl_matrix * QR, double * rcond, gsl_vector * work); + +/* complex QR decomposition */ + +int gsl_linalg_complex_QR_decomp (gsl_matrix_complex * A, gsl_vector_complex * tau); + +int gsl_linalg_complex_QR_decomp_r (gsl_matrix_complex * A, gsl_matrix_complex * T); + +int gsl_linalg_complex_QR_solve (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, + const gsl_vector_complex * b, gsl_vector_complex * x); + +int gsl_linalg_complex_QR_solve_r (const gsl_matrix_complex * QR, const gsl_matrix_complex * T, + const gsl_vector_complex * b, gsl_vector_complex * x); + +int gsl_linalg_complex_QR_svx (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, gsl_vector_complex * x); + +int gsl_linalg_complex_QR_lssolve (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, + const gsl_vector_complex * b, gsl_vector_complex * x, + gsl_vector_complex * residual); + +int gsl_linalg_complex_QR_lssolve_r (const gsl_matrix_complex * QR, const gsl_matrix_complex * T, + const gsl_vector_complex * b, gsl_vector_complex * x, gsl_vector_complex * work); + +int gsl_linalg_complex_QR_QHvec (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, gsl_vector_complex * v); + +int gsl_linalg_complex_QR_QHvec_r(const gsl_matrix_complex * QR, const gsl_matrix_complex * T, + gsl_vector_complex * b, gsl_vector_complex * work); + +int gsl_linalg_complex_QR_Qvec (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, gsl_vector_complex * v); + +int gsl_linalg_complex_QR_unpack (const gsl_matrix_complex * QR, const gsl_vector_complex * tau, + gsl_matrix_complex * Q, gsl_matrix_complex * R); + +int gsl_linalg_complex_QR_unpack_r(const gsl_matrix_complex * QR, const gsl_matrix_complex * T, + gsl_matrix_complex * Q, gsl_matrix_complex * R); + +/* banded QR decomposition */ + +int gsl_linalg_QR_band_decomp_L2 (const size_t M, const size_t p, const size_t q, + gsl_matrix * AB, gsl_vector * tau); + +int gsl_linalg_QR_band_unpack_L2 (const size_t p, const size_t q, const gsl_matrix * QRB, + const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * R); + +/* Q R P^T decomposition */ + +int gsl_linalg_QRPT_decomp (gsl_matrix * A, + gsl_vector * tau, + gsl_permutation * p, + int *signum, + gsl_vector * norm); + +int gsl_linalg_QRPT_decomp2 (const gsl_matrix * A, + gsl_matrix * q, gsl_matrix * r, + gsl_vector * tau, + gsl_permutation * p, + int *signum, + gsl_vector * norm); + +int gsl_linalg_QRPT_solve (const gsl_matrix * QR, + const gsl_vector * tau, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_QRPT_lssolve (const gsl_matrix * QR, + const gsl_vector * tau, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x, + gsl_vector * residual); + +int gsl_linalg_QRPT_lssolve2 (const gsl_matrix * QR, + const gsl_vector * tau, + const gsl_permutation * p, + const gsl_vector * b, + const size_t rank, + gsl_vector * x, + gsl_vector * residual); + +int gsl_linalg_QRPT_svx (const gsl_matrix * QR, + const gsl_vector * tau, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_QRPT_QRsolve (const gsl_matrix * Q, + const gsl_matrix * R, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_QRPT_Rsolve (const gsl_matrix * QR, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_QRPT_Rsvx (const gsl_matrix * QR, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_QRPT_update (gsl_matrix * Q, + gsl_matrix * R, + const gsl_permutation * p, + gsl_vector * u, + const gsl_vector * v); + +size_t gsl_linalg_QRPT_rank (const gsl_matrix * QR, const double tol); + +int gsl_linalg_QRPT_rcond(const gsl_matrix * QR, double * rcond, gsl_vector * work); + +/* triangle on top of diagonal QR decomposition */ + +int gsl_linalg_QR_UD_decomp (gsl_matrix * U, const gsl_vector * D, gsl_matrix * Y, gsl_matrix * T); + +int gsl_linalg_QR_UD_lssolve (const gsl_matrix * R, const gsl_matrix * Y, const gsl_matrix * T, + const gsl_vector * b, gsl_vector * x, gsl_vector * work); + +/* triangle on top of rectangle QR decomposition */ + +int gsl_linalg_QR_UR_decomp (gsl_matrix * S, gsl_matrix * A, gsl_matrix * T); + +/* triangle on top of triangle QR decomposition */ + +int gsl_linalg_QR_UU_decomp (gsl_matrix * U, gsl_matrix * S, gsl_matrix * T); + +int gsl_linalg_QR_UU_lssolve (const gsl_matrix * R, const gsl_matrix * Y, const gsl_matrix * T, + const gsl_vector * b, gsl_vector * x, gsl_vector * work); + +int gsl_linalg_QR_UU_QTvec(const gsl_matrix * Y, const gsl_matrix * T, gsl_vector * b, gsl_vector * work); + +/* triangle on top of trapezoidal QR decomposition */ + +int gsl_linalg_QR_UZ_decomp (gsl_matrix * S, gsl_matrix * A, gsl_matrix * T); + +/* QL decomposition */ + +int gsl_linalg_QL_decomp (gsl_matrix * A, gsl_vector * tau); + +int gsl_linalg_QL_unpack (const gsl_matrix * QL, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * L); + +/* COD decomposition */ + +int gsl_linalg_COD_decomp(gsl_matrix * A, gsl_vector * tau_Q, gsl_vector * tau_Z, + gsl_permutation * p, size_t * rank, gsl_vector * work); + +int gsl_linalg_COD_decomp_e(gsl_matrix * A, gsl_vector * tau_Q, gsl_vector * tau_Z, + gsl_permutation * p, double tol, size_t * rank, gsl_vector * work); + +int gsl_linalg_COD_lssolve (const gsl_matrix * QRZT, const gsl_vector * tau_Q, const gsl_vector * tau_Z, + const gsl_permutation * perm, const size_t rank, const gsl_vector * b, + gsl_vector * x, gsl_vector * residual); + +int +gsl_linalg_COD_lssolve2 (const double lambda, const gsl_matrix * QRZT, const gsl_vector * tau_Q, const gsl_vector * tau_Z, + const gsl_permutation * perm, const size_t rank, const gsl_vector * b, + gsl_vector * x, gsl_vector * residual, gsl_matrix * S, gsl_vector * work); + +int gsl_linalg_COD_unpack(const gsl_matrix * QRZT, const gsl_vector * tau_Q, + const gsl_vector * tau_Z, const size_t rank, gsl_matrix * Q, + gsl_matrix * R, gsl_matrix * Z); + +int gsl_linalg_COD_matZ(const gsl_matrix * QRZT, const gsl_vector * tau_Z, const size_t rank, + gsl_matrix * A, gsl_vector * work); + +/* LQ decomposition */ + +int gsl_linalg_LQ_decomp (gsl_matrix * A, gsl_vector * tau); + +int gsl_linalg_LQ_lssolve(const gsl_matrix * LQ, const gsl_vector * tau, + const gsl_vector * b, gsl_vector * x, gsl_vector * residual); + +int gsl_linalg_LQ_QTvec(const gsl_matrix * LQ, const gsl_vector * tau, gsl_vector * v); + +int gsl_linalg_LQ_solve_T (const gsl_matrix * LQ, const gsl_vector * tau, + const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_LQ_svx_T (const gsl_matrix * LQ, const gsl_vector * tau, + gsl_vector * x); + +int gsl_linalg_LQ_lssolve_T (const gsl_matrix * LQ, const gsl_vector * tau, + const gsl_vector * b, gsl_vector * x, + gsl_vector * residual); + +int gsl_linalg_LQ_Lsolve_T (const gsl_matrix * LQ, const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_LQ_Lsvx_T (const gsl_matrix * LQ, gsl_vector * x); + +int gsl_linalg_L_solve_T (const gsl_matrix * L, const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_LQ_vecQ (const gsl_matrix * LQ, const gsl_vector * tau, + gsl_vector * v); + +int gsl_linalg_LQ_vecQT (const gsl_matrix * LQ, const gsl_vector * tau, + gsl_vector * v); + +int gsl_linalg_LQ_unpack (const gsl_matrix * LQ, const gsl_vector * tau, + gsl_matrix * Q, gsl_matrix * L); + +int gsl_linalg_LQ_update (gsl_matrix * Q, gsl_matrix * R, + const gsl_vector * v, gsl_vector * w); +int gsl_linalg_LQ_LQsolve (gsl_matrix * Q, gsl_matrix * L, + const gsl_vector * b, gsl_vector * x); + +/* P^T L Q decomposition */ + +int gsl_linalg_PTLQ_decomp (gsl_matrix * A, gsl_vector * tau, + gsl_permutation * p, int *signum, + gsl_vector * norm); + +int gsl_linalg_PTLQ_decomp2 (const gsl_matrix * A, gsl_matrix * q, + gsl_matrix * r, gsl_vector * tau, + gsl_permutation * p, int *signum, + gsl_vector * norm); + +int gsl_linalg_PTLQ_solve_T (const gsl_matrix * QR, + const gsl_vector * tau, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_PTLQ_svx_T (const gsl_matrix * LQ, + const gsl_vector * tau, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_PTLQ_LQsolve_T (const gsl_matrix * Q, const gsl_matrix * L, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_PTLQ_Lsolve_T (const gsl_matrix * LQ, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_PTLQ_Lsvx_T (const gsl_matrix * LQ, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_PTLQ_update (gsl_matrix * Q, gsl_matrix * L, + const gsl_permutation * p, + const gsl_vector * v, gsl_vector * w); + +/* Cholesky Decomposition */ + +int gsl_linalg_cholesky_decomp (gsl_matrix * A); +int gsl_linalg_cholesky_decomp1 (gsl_matrix * A); + +int gsl_linalg_cholesky_solve (const gsl_matrix * cholesky, + const gsl_vector * b, + gsl_vector * x); +int gsl_linalg_cholesky_solve_mat (const gsl_matrix * cholesky, + const gsl_matrix * B, + gsl_matrix * X); + +int gsl_linalg_cholesky_svx (const gsl_matrix * cholesky, + gsl_vector * x); +int gsl_linalg_cholesky_svx_mat (const gsl_matrix * cholesky, + gsl_matrix * X); + +int gsl_linalg_cholesky_invert(gsl_matrix * cholesky); + +/* Cholesky decomposition with unit-diagonal triangular parts. + * A = L D L^T, where diag(L) = (1,1,...,1). + * Upon exit, A contains L and L^T as for Cholesky, and + * the diagonal of A is (1,1,...,1). The vector Dis set + * to the diagonal elements of the diagonal matrix D. + */ +int gsl_linalg_cholesky_decomp_unit(gsl_matrix * A, gsl_vector * D); + +int gsl_linalg_cholesky_scale(const gsl_matrix * A, gsl_vector * S); + +int gsl_linalg_cholesky_scale_apply(gsl_matrix * A, const gsl_vector * S); + +int gsl_linalg_cholesky_decomp2(gsl_matrix * A, gsl_vector * S); + +int gsl_linalg_cholesky_svx2 (const gsl_matrix * LLT, + const gsl_vector * S, + gsl_vector * x); + +int gsl_linalg_cholesky_solve2 (const gsl_matrix * LLT, + const gsl_vector * S, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_cholesky_rcond (const gsl_matrix * LLT, double * rcond, + gsl_vector * work); + +/* Complex Cholesky Decomposition */ + +int gsl_linalg_complex_cholesky_decomp (gsl_matrix_complex * A); + +int gsl_linalg_complex_cholesky_solve (const gsl_matrix_complex * cholesky, + const gsl_vector_complex * b, + gsl_vector_complex * x); + +int gsl_linalg_complex_cholesky_svx (const gsl_matrix_complex * cholesky, + gsl_vector_complex * x); + +int gsl_linalg_complex_cholesky_invert(gsl_matrix_complex * cholesky); + +/* Pivoted Cholesky LDLT decomposition */ + +int gsl_linalg_pcholesky_decomp (gsl_matrix * A, gsl_permutation * p); + +int gsl_linalg_pcholesky_solve(const gsl_matrix * LDLT, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_pcholesky_svx(const gsl_matrix * LDLT, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_pcholesky_decomp2(gsl_matrix * A, gsl_permutation * p, + gsl_vector * S); + +int gsl_linalg_pcholesky_solve2(const gsl_matrix * LDLT, + const gsl_permutation * p, + const gsl_vector * S, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_pcholesky_svx2(const gsl_matrix * LDLT, + const gsl_permutation * p, + const gsl_vector * S, + gsl_vector * x); + +int gsl_linalg_pcholesky_invert(const gsl_matrix * LDLT, const gsl_permutation * p, + gsl_matrix * Ainv); + +int gsl_linalg_pcholesky_rcond (const gsl_matrix * LDLT, const gsl_permutation * p, + double * rcond, gsl_vector * work); + +/* Modified Cholesky decomposition */ + +int gsl_linalg_mcholesky_decomp (gsl_matrix * A, gsl_permutation * p, + gsl_vector * E); + +int gsl_linalg_mcholesky_solve(const gsl_matrix * LDLT, + const gsl_permutation * p, + const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_mcholesky_svx(const gsl_matrix * LDLT, + const gsl_permutation * p, + gsl_vector * x); + +int gsl_linalg_mcholesky_rcond (const gsl_matrix * LDLT, const gsl_permutation * p, + double * rcond, gsl_vector * work); + +int gsl_linalg_mcholesky_invert(const gsl_matrix * LDLT, const gsl_permutation * p, + gsl_matrix * Ainv); + +/* Banded Cholesky decomposition */ + +int gsl_linalg_cholesky_band_decomp(gsl_matrix * A); + +int gsl_linalg_cholesky_band_solve (const gsl_matrix * LLT, const gsl_vector * b, + gsl_vector * x); + +int gsl_linalg_cholesky_band_svx (const gsl_matrix * LLT, gsl_vector * x); + +int gsl_linalg_cholesky_band_solvem (const gsl_matrix * LLT, const gsl_matrix * B, + gsl_matrix * X); + +int gsl_linalg_cholesky_band_svxm (const gsl_matrix * LLT, gsl_matrix * X); + +int gsl_linalg_cholesky_band_invert (const gsl_matrix * LLT, gsl_matrix * Ainv); + +int gsl_linalg_cholesky_band_unpack (const gsl_matrix * LLT, gsl_matrix * L); + +int gsl_linalg_cholesky_band_scale(const gsl_matrix * A, gsl_vector * S); + +int gsl_linalg_cholesky_band_scale_apply(gsl_matrix * A, const gsl_vector * S); + +int gsl_linalg_cholesky_band_rcond (const gsl_matrix * LLT, double * rcond, gsl_vector * work); + +/* L D L^T decomposition */ + +int gsl_linalg_ldlt_decomp (gsl_matrix * A); + +int gsl_linalg_ldlt_solve (const gsl_matrix * LDLT, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_ldlt_svx (const gsl_matrix * LDLT, gsl_vector * x); + +int gsl_linalg_ldlt_rcond (const gsl_matrix * LDLT, double * rcond, gsl_vector * work); + +/* Banded L D L^T decomposition */ + +int gsl_linalg_ldlt_band_decomp (gsl_matrix * A); + +int gsl_linalg_ldlt_band_solve (const gsl_matrix * LDLT, const gsl_vector * b, gsl_vector * x); + +int gsl_linalg_ldlt_band_svx (const gsl_matrix * LDLT, gsl_vector * x); + +int gsl_linalg_ldlt_band_unpack (const gsl_matrix * LDLT, gsl_matrix * L, gsl_vector * D); + +int gsl_linalg_ldlt_band_rcond (const gsl_matrix * LDLT, double * rcond, gsl_vector * work); + +/* Symmetric to symmetric tridiagonal decomposition */ + +int gsl_linalg_symmtd_decomp (gsl_matrix * A, + gsl_vector * tau); + +int gsl_linalg_symmtd_unpack (const gsl_matrix * A, + const gsl_vector * tau, + gsl_matrix * Q, + gsl_vector * diag, + gsl_vector * subdiag); + +int gsl_linalg_symmtd_unpack_T (const gsl_matrix * A, + gsl_vector * diag, + gsl_vector * subdiag); + +/* Hermitian to symmetric tridiagonal decomposition */ + +int gsl_linalg_hermtd_decomp (gsl_matrix_complex * A, + gsl_vector_complex * tau); + +int gsl_linalg_hermtd_unpack (const gsl_matrix_complex * A, + const gsl_vector_complex * tau, + gsl_matrix_complex * U, + gsl_vector * diag, + gsl_vector * sudiag); + +int gsl_linalg_hermtd_unpack_T (const gsl_matrix_complex * A, + gsl_vector * diag, + gsl_vector * subdiag); + +/* Linear Solve Using Householder Transformations + + * exceptions: + */ + +int gsl_linalg_HH_solve (gsl_matrix * A, const gsl_vector * b, gsl_vector * x); +int gsl_linalg_HH_svx (gsl_matrix * A, gsl_vector * x); + +/* Linear solve for a symmetric tridiagonal system. + + * The input vectors represent the NxN matrix as follows: + * + * diag[0] offdiag[0] 0 ... + * offdiag[0] diag[1] offdiag[1] ... + * 0 offdiag[1] diag[2] ... + * 0 0 offdiag[2] ... + * ... ... ... ... + */ +int gsl_linalg_solve_symm_tridiag (const gsl_vector * diag, + const gsl_vector * offdiag, + const gsl_vector * b, + gsl_vector * x); + +/* Linear solve for a nonsymmetric tridiagonal system. + + * The input vectors represent the NxN matrix as follows: + * + * diag[0] abovediag[0] 0 ... + * belowdiag[0] diag[1] abovediag[1] ... + * 0 belowdiag[1] diag[2] ... + * 0 0 belowdiag[2] ... + * ... ... ... ... + */ +int gsl_linalg_solve_tridiag (const gsl_vector * diag, + const gsl_vector * abovediag, + const gsl_vector * belowdiag, + const gsl_vector * b, + gsl_vector * x); + + +/* Linear solve for a symmetric cyclic tridiagonal system. + + * The input vectors represent the NxN matrix as follows: + * + * diag[0] offdiag[0] 0 ..... offdiag[N-1] + * offdiag[0] diag[1] offdiag[1] ..... + * 0 offdiag[1] diag[2] ..... + * 0 0 offdiag[2] ..... + * ... ... + * offdiag[N-1] ... + */ +int gsl_linalg_solve_symm_cyc_tridiag (const gsl_vector * diag, + const gsl_vector * offdiag, + const gsl_vector * b, + gsl_vector * x); + +/* Linear solve for a nonsymmetric cyclic tridiagonal system. + + * The input vectors represent the NxN matrix as follows: + * + * diag[0] abovediag[0] 0 ..... belowdiag[N-1] + * belowdiag[0] diag[1] abovediag[1] ..... + * 0 belowdiag[1] diag[2] + * 0 0 belowdiag[2] ..... + * ... ... + * abovediag[N-1] ... + */ +int gsl_linalg_solve_cyc_tridiag (const gsl_vector * diag, + const gsl_vector * abovediag, + const gsl_vector * belowdiag, + const gsl_vector * b, + gsl_vector * x); + + +/* Bidiagonal decomposition */ + +int gsl_linalg_bidiag_decomp (gsl_matrix * A, + gsl_vector * tau_U, + gsl_vector * tau_V); + +int gsl_linalg_bidiag_unpack (const gsl_matrix * A, + const gsl_vector * tau_U, + gsl_matrix * U, + const gsl_vector * tau_V, + gsl_matrix * V, + gsl_vector * diag, + gsl_vector * superdiag); + +int gsl_linalg_bidiag_unpack2 (gsl_matrix * A, + gsl_vector * tau_U, + gsl_vector * tau_V, + gsl_matrix * V); + +int gsl_linalg_bidiag_unpack_B (const gsl_matrix * A, + gsl_vector * diag, + gsl_vector * superdiag); + +/* Balancing */ + +int gsl_linalg_balance_matrix (gsl_matrix * A, gsl_vector * D); +int gsl_linalg_balance_accum (gsl_matrix * A, gsl_vector * D); +int gsl_linalg_balance_columns (gsl_matrix * A, gsl_vector * D); + +/* condition estimation */ + +int gsl_linalg_tri_rcond(CBLAS_UPLO_t Uplo, const gsl_matrix * A, double * rcond, gsl_vector * work); +int gsl_linalg_tri_upper_rcond(const gsl_matrix * A, double * rcond, gsl_vector * work); +int gsl_linalg_tri_lower_rcond(const gsl_matrix * A, double * rcond, gsl_vector * work); +int gsl_linalg_invnorm1(const size_t N, + int (* Ainvx)(CBLAS_TRANSPOSE_t TransA, gsl_vector * x, void * params), + void * params, double * Ainvnorm, gsl_vector * work); + +/* triangular matrices */ + +int gsl_linalg_tri_upper_invert(gsl_matrix * T); +int gsl_linalg_tri_lower_invert(gsl_matrix * T); +int gsl_linalg_tri_upper_unit_invert(gsl_matrix * T); +int gsl_linalg_tri_lower_unit_invert(gsl_matrix * T); + +int gsl_linalg_tri_invert(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix * T); +int gsl_linalg_complex_tri_invert(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_complex * T); + +int gsl_linalg_tri_LTL(gsl_matrix * L); +int gsl_linalg_tri_UL(gsl_matrix * LU); +int gsl_linalg_complex_tri_LHL(gsl_matrix_complex * L); +int gsl_linalg_complex_tri_UL(gsl_matrix_complex * LU); + +INLINE_DECL void gsl_linalg_givens (const double a, const double b, + double *c, double *s); +INLINE_DECL void gsl_linalg_givens_gv (gsl_vector * v, const size_t i, + const size_t j, const double c, + const double s); + +#ifdef HAVE_INLINE + +/* Generate a Givens rotation (cos,sin) which takes v=(x,y) to (|v|,0) + From Golub and Van Loan, "Matrix Computations", Section 5.1.8 */ +INLINE_FUN +void +gsl_linalg_givens (const double a, const double b, double *c, double *s) +{ + if (b == 0) + { + *c = 1; + *s = 0; + } + else if (fabs (b) > fabs (a)) + { + double t = -a / b; + double s1 = 1.0 / sqrt (1 + t * t); + *s = s1; + *c = s1 * t; + } + else + { + double t = -b / a; + double c1 = 1.0 / sqrt (1 + t * t); + *c = c1; + *s = c1 * t; + } +} /* gsl_linalg_givens() */ + +INLINE_FUN +void +gsl_linalg_givens_gv (gsl_vector * v, const size_t i, const size_t j, + const double c, const double s) +{ + /* Apply rotation to vector v' = G^T v */ + + double vi = gsl_vector_get (v, i); + double vj = gsl_vector_get (v, j); + gsl_vector_set (v, i, c * vi - s * vj); + gsl_vector_set (v, j, s * vi + c * vj); +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_LINALG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_machine.h b/ChaosDataPlayer/GSL/include/gsl/gsl_machine.h new file mode 100644 index 0000000..c44ffc2 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_machine.h @@ -0,0 +1,104 @@ +/* Author: B. Gough and G. Jungman */ +#ifndef __GSL_MACHINE_H__ +#define __GSL_MACHINE_H__ + +#include +#include + +/* magic constants; mostly for the benefit of the implementation */ + +/* -*-MACHINE CONSTANTS-*- + * + * PLATFORM: Whiz-O-Matic 9000 + * FP_PLATFORM: IEEE-Virtual + * HOSTNAME: nnn.lanl.gov + * DATE: Fri Nov 20 17:53:26 MST 1998 + */ +#define GSL_DBL_EPSILON 2.2204460492503131e-16 +#define GSL_SQRT_DBL_EPSILON 1.4901161193847656e-08 +#define GSL_ROOT3_DBL_EPSILON 6.0554544523933429e-06 +#define GSL_ROOT4_DBL_EPSILON 1.2207031250000000e-04 +#define GSL_ROOT5_DBL_EPSILON 7.4009597974140505e-04 +#define GSL_ROOT6_DBL_EPSILON 2.4607833005759251e-03 +#define GSL_LOG_DBL_EPSILON (-3.6043653389117154e+01) + +#define GSL_DBL_MIN 2.2250738585072014e-308 +#define GSL_SQRT_DBL_MIN 1.4916681462400413e-154 +#define GSL_ROOT3_DBL_MIN 2.8126442852362996e-103 +#define GSL_ROOT4_DBL_MIN 1.2213386697554620e-77 +#define GSL_ROOT5_DBL_MIN 2.9476022969691763e-62 +#define GSL_ROOT6_DBL_MIN 5.3034368905798218e-52 +#define GSL_LOG_DBL_MIN (-7.0839641853226408e+02) + +#define GSL_DBL_MAX 1.7976931348623157e+308 +#define GSL_SQRT_DBL_MAX 1.3407807929942596e+154 +#define GSL_ROOT3_DBL_MAX 5.6438030941222897e+102 +#define GSL_ROOT4_DBL_MAX 1.1579208923731620e+77 +#define GSL_ROOT5_DBL_MAX 4.4765466227572707e+61 +#define GSL_ROOT6_DBL_MAX 2.3756689782295612e+51 +#define GSL_LOG_DBL_MAX 7.0978271289338397e+02 + +#define GSL_FLT_EPSILON 1.1920928955078125e-07 +#define GSL_SQRT_FLT_EPSILON 3.4526698300124393e-04 +#define GSL_ROOT3_FLT_EPSILON 4.9215666011518501e-03 +#define GSL_ROOT4_FLT_EPSILON 1.8581361171917516e-02 +#define GSL_ROOT5_FLT_EPSILON 4.1234622211652937e-02 +#define GSL_ROOT6_FLT_EPSILON 7.0153878019335827e-02 +#define GSL_LOG_FLT_EPSILON (-1.5942385152878742e+01) + +#define GSL_FLT_MIN 1.1754943508222875e-38 +#define GSL_SQRT_FLT_MIN 1.0842021724855044e-19 +#define GSL_ROOT3_FLT_MIN 2.2737367544323241e-13 +#define GSL_ROOT4_FLT_MIN 3.2927225399135965e-10 +#define GSL_ROOT5_FLT_MIN 2.5944428542140822e-08 +#define GSL_ROOT6_FLT_MIN 4.7683715820312542e-07 +#define GSL_LOG_FLT_MIN (-8.7336544750553102e+01) + +#define GSL_FLT_MAX 3.4028234663852886e+38 +#define GSL_SQRT_FLT_MAX 1.8446743523953730e+19 +#define GSL_ROOT3_FLT_MAX 6.9814635196223242e+12 +#define GSL_ROOT4_FLT_MAX 4.2949672319999986e+09 +#define GSL_ROOT5_FLT_MAX 5.0859007855960041e+07 +#define GSL_ROOT6_FLT_MAX 2.6422459233807749e+06 +#define GSL_LOG_FLT_MAX 8.8722839052068352e+01 + +#define GSL_SFLT_EPSILON 4.8828125000000000e-04 +#define GSL_SQRT_SFLT_EPSILON 2.2097086912079612e-02 +#define GSL_ROOT3_SFLT_EPSILON 7.8745065618429588e-02 +#define GSL_ROOT4_SFLT_EPSILON 1.4865088937534013e-01 +#define GSL_ROOT5_SFLT_EPSILON 2.1763764082403100e-01 +#define GSL_ROOT6_SFLT_EPSILON 2.8061551207734325e-01 +#define GSL_LOG_SFLT_EPSILON (-7.6246189861593985e+00) + +/* !MACHINE CONSTANTS! */ + + +/* a little internal backwards compatibility */ +#define GSL_MACH_EPS GSL_DBL_EPSILON + + + +/* Here are the constants related to or derived from + * machine constants. These are not to be confused with + * the constants that define various precision levels + * for the precision/error system. + * + * This information is determined at configure time + * and is platform dependent. Edit at your own risk. + * + * PLATFORM: WHIZ-O-MATIC + * CONFIG-DATE: Thu Nov 19 19:27:18 MST 1998 + * CONFIG-HOST: nnn.lanl.gov + */ + +/* machine precision constants */ +/* #define GSL_MACH_EPS 1.0e-15 */ +#define GSL_SQRT_MACH_EPS 3.2e-08 +#define GSL_ROOT3_MACH_EPS 1.0e-05 +#define GSL_ROOT4_MACH_EPS 0.000178 +#define GSL_ROOT5_MACH_EPS 0.00100 +#define GSL_ROOT6_MACH_EPS 0.00316 +#define GSL_LOG_MACH_EPS (-34.54) + + +#endif /* __GSL_MACHINE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_math.h b/ChaosDataPlayer/GSL/include/gsl/gsl_math.h new file mode 100644 index 0000000..2d09df1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_math.h @@ -0,0 +1,164 @@ +/* gsl_math.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATH_H__ +#define __GSL_MATH_H__ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef M_E +#define M_E 2.71828182845904523536028747135 /* e */ +#endif + +#ifndef M_LOG2E +#define M_LOG2E 1.44269504088896340735992468100 /* log_2 (e) */ +#endif + +#ifndef M_LOG10E +#define M_LOG10E 0.43429448190325182765112891892 /* log_10 (e) */ +#endif + +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880168872421 /* sqrt(2) */ +#endif + +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440084436210 /* sqrt(1/2) */ +#endif + + +#ifndef M_SQRT3 +#define M_SQRT3 1.73205080756887729352744634151 /* sqrt(3) */ +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338328 /* pi */ +#endif + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923132169164 /* pi/2 */ +#endif + +#ifndef M_PI_4 +#define M_PI_4 0.78539816339744830961566084582 /* pi/4 */ +#endif + +#ifndef M_SQRTPI +#define M_SQRTPI 1.77245385090551602729816748334 /* sqrt(pi) */ +#endif + +#ifndef M_2_SQRTPI +#define M_2_SQRTPI 1.12837916709551257389615890312 /* 2/sqrt(pi) */ +#endif + +#ifndef M_1_PI +#define M_1_PI 0.31830988618379067153776752675 /* 1/pi */ +#endif + +#ifndef M_2_PI +#define M_2_PI 0.63661977236758134307553505349 /* 2/pi */ +#endif + +#ifndef M_LN10 +#define M_LN10 2.30258509299404568401799145468 /* ln(10) */ +#endif + +#ifndef M_LN2 +#define M_LN2 0.69314718055994530941723212146 /* ln(2) */ +#endif + +#ifndef M_LNPI +#define M_LNPI 1.14472988584940017414342735135 /* ln(pi) */ +#endif + +#ifndef M_EULER +#define M_EULER 0.57721566490153286060651209008 /* Euler constant */ +#endif + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* other needlessly compulsive abstractions */ + +#define GSL_IS_ODD(n) ((n) & 1) +#define GSL_IS_EVEN(n) (!(GSL_IS_ODD(n))) +#define GSL_SIGN(x) ((x) >= 0.0 ? 1 : -1) + +/* Return nonzero if x is a real number, i.e. non NaN or infinite. */ +#define GSL_IS_REAL(x) (gsl_finite(x)) + +/* Definition of an arbitrary function with parameters */ + +struct gsl_function_struct +{ + double (* function) (double x, void * params); + void * params; +}; + +typedef struct gsl_function_struct gsl_function ; + +#define GSL_FN_EVAL(F,x) (*((F)->function))(x,(F)->params) + +/* Definition of an arbitrary function returning two values, r1, r2 */ + +struct gsl_function_fdf_struct +{ + double (* f) (double x, void * params); + double (* df) (double x, void * params); + void (* fdf) (double x, void * params, double * f, double * df); + void * params; +}; + +typedef struct gsl_function_fdf_struct gsl_function_fdf ; + +#define GSL_FN_FDF_EVAL_F(FDF,x) (*((FDF)->f))(x,(FDF)->params) +#define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) +#define GSL_FN_FDF_EVAL_F_DF(FDF,x,y,dy) (*((FDF)->fdf))(x,(FDF)->params,(y),(dy)) + + +/* Definition of an arbitrary vector-valued function with parameters */ + +struct gsl_function_vec_struct +{ + int (* function) (double x, double y[], void * params); + void * params; +}; + +typedef struct gsl_function_vec_struct gsl_function_vec ; + +#define GSL_FN_VEC_EVAL(F,x,y) (*((F)->function))(x,y,(F)->params) + +__END_DECLS + +#endif /* __GSL_MATH_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix.h new file mode 100644 index 0000000..9b7ed76 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix.h @@ -0,0 +1,25 @@ +#ifndef __GSL_MATRIX_H__ +#define __GSL_MATRIX_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + + +#endif /* __GSL_MATRIX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_char.h new file mode 100644 index 0000000..96930db --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_char.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_CHAR_H__ +#define __GSL_MATRIX_CHAR_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + char * data; + gsl_block_char * block; + int owner; +} gsl_matrix_char; + +typedef struct +{ + gsl_matrix_char matrix; +} _gsl_matrix_char_view; + +typedef _gsl_matrix_char_view gsl_matrix_char_view; + +typedef struct +{ + gsl_matrix_char matrix; +} _gsl_matrix_char_const_view; + +typedef const _gsl_matrix_char_const_view gsl_matrix_char_const_view; + +/* Allocation */ + +gsl_matrix_char * +gsl_matrix_char_alloc (const size_t n1, const size_t n2); + +gsl_matrix_char * +gsl_matrix_char_calloc (const size_t n1, const size_t n2); + +gsl_matrix_char * +gsl_matrix_char_alloc_from_block (gsl_block_char * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_char * +gsl_matrix_char_alloc_from_matrix (gsl_matrix_char * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_char * +gsl_vector_char_alloc_row_from_matrix (gsl_matrix_char * m, + const size_t i); + +gsl_vector_char * +gsl_vector_char_alloc_col_from_matrix (gsl_matrix_char * m, + const size_t j); + +void gsl_matrix_char_free (gsl_matrix_char * m); + +/* Views */ + +_gsl_matrix_char_view +gsl_matrix_char_submatrix (gsl_matrix_char * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_char_view +gsl_matrix_char_row (gsl_matrix_char * m, const size_t i); + +_gsl_vector_char_view +gsl_matrix_char_column (gsl_matrix_char * m, const size_t j); + +_gsl_vector_char_view +gsl_matrix_char_diagonal (gsl_matrix_char * m); + +_gsl_vector_char_view +gsl_matrix_char_subdiagonal (gsl_matrix_char * m, const size_t k); + +_gsl_vector_char_view +gsl_matrix_char_superdiagonal (gsl_matrix_char * m, const size_t k); + +_gsl_vector_char_view +gsl_matrix_char_subrow (gsl_matrix_char * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_char_view +gsl_matrix_char_subcolumn (gsl_matrix_char * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_char_view +gsl_matrix_char_view_array (char * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_char_view +gsl_matrix_char_view_array_with_tda (char * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_char_view +gsl_matrix_char_view_vector (gsl_vector_char * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_char_view +gsl_matrix_char_view_vector_with_tda (gsl_vector_char * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_char_const_view +gsl_matrix_char_const_submatrix (const gsl_matrix_char * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_char_const_view +gsl_matrix_char_const_row (const gsl_matrix_char * m, + const size_t i); + +_gsl_vector_char_const_view +gsl_matrix_char_const_column (const gsl_matrix_char * m, + const size_t j); + +_gsl_vector_char_const_view +gsl_matrix_char_const_diagonal (const gsl_matrix_char * m); + +_gsl_vector_char_const_view +gsl_matrix_char_const_subdiagonal (const gsl_matrix_char * m, + const size_t k); + +_gsl_vector_char_const_view +gsl_matrix_char_const_superdiagonal (const gsl_matrix_char * m, + const size_t k); + +_gsl_vector_char_const_view +gsl_matrix_char_const_subrow (const gsl_matrix_char * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_char_const_view +gsl_matrix_char_const_subcolumn (const gsl_matrix_char * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_char_const_view +gsl_matrix_char_const_view_array (const char * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_char_const_view +gsl_matrix_char_const_view_array_with_tda (const char * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_char_const_view +gsl_matrix_char_const_view_vector (const gsl_vector_char * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_char_const_view +gsl_matrix_char_const_view_vector_with_tda (const gsl_vector_char * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_char_set_zero (gsl_matrix_char * m); +void gsl_matrix_char_set_identity (gsl_matrix_char * m); +void gsl_matrix_char_set_all (gsl_matrix_char * m, char x); + +int gsl_matrix_char_fread (FILE * stream, gsl_matrix_char * m) ; +int gsl_matrix_char_fwrite (FILE * stream, const gsl_matrix_char * m) ; +int gsl_matrix_char_fscanf (FILE * stream, gsl_matrix_char * m); +int gsl_matrix_char_fprintf (FILE * stream, const gsl_matrix_char * m, const char * format); + +int gsl_matrix_char_memcpy(gsl_matrix_char * dest, const gsl_matrix_char * src); +int gsl_matrix_char_swap(gsl_matrix_char * m1, gsl_matrix_char * m2); +int gsl_matrix_char_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_char * dest, const gsl_matrix_char * src); + +int gsl_matrix_char_swap_rows(gsl_matrix_char * m, const size_t i, const size_t j); +int gsl_matrix_char_swap_columns(gsl_matrix_char * m, const size_t i, const size_t j); +int gsl_matrix_char_swap_rowcol(gsl_matrix_char * m, const size_t i, const size_t j); +int gsl_matrix_char_transpose (gsl_matrix_char * m); +int gsl_matrix_char_transpose_memcpy (gsl_matrix_char * dest, const gsl_matrix_char * src); +int gsl_matrix_char_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_char * dest, const gsl_matrix_char * src); + +char gsl_matrix_char_max (const gsl_matrix_char * m); +char gsl_matrix_char_min (const gsl_matrix_char * m); +void gsl_matrix_char_minmax (const gsl_matrix_char * m, char * min_out, char * max_out); + +void gsl_matrix_char_max_index (const gsl_matrix_char * m, size_t * imax, size_t *jmax); +void gsl_matrix_char_min_index (const gsl_matrix_char * m, size_t * imin, size_t *jmin); +void gsl_matrix_char_minmax_index (const gsl_matrix_char * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_char_equal (const gsl_matrix_char * a, const gsl_matrix_char * b); + +int gsl_matrix_char_isnull (const gsl_matrix_char * m); +int gsl_matrix_char_ispos (const gsl_matrix_char * m); +int gsl_matrix_char_isneg (const gsl_matrix_char * m); +int gsl_matrix_char_isnonneg (const gsl_matrix_char * m); + +char gsl_matrix_char_norm1 (const gsl_matrix_char * m); + +int gsl_matrix_char_add (gsl_matrix_char * a, const gsl_matrix_char * b); +int gsl_matrix_char_sub (gsl_matrix_char * a, const gsl_matrix_char * b); +int gsl_matrix_char_mul_elements (gsl_matrix_char * a, const gsl_matrix_char * b); +int gsl_matrix_char_div_elements (gsl_matrix_char * a, const gsl_matrix_char * b); +int gsl_matrix_char_scale (gsl_matrix_char * a, const char x); +int gsl_matrix_char_scale_rows (gsl_matrix_char * a, const gsl_vector_char * x); +int gsl_matrix_char_scale_columns (gsl_matrix_char * a, const gsl_vector_char * x); +int gsl_matrix_char_add_constant (gsl_matrix_char * a, const char x); +int gsl_matrix_char_add_diagonal (gsl_matrix_char * a, const char x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_char_get_row(gsl_vector_char * v, const gsl_matrix_char * m, const size_t i); +int gsl_matrix_char_get_col(gsl_vector_char * v, const gsl_matrix_char * m, const size_t j); +int gsl_matrix_char_set_row(gsl_matrix_char * m, const size_t i, const gsl_vector_char * v); +int gsl_matrix_char_set_col(gsl_matrix_char * m, const size_t j, const gsl_vector_char * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL char gsl_matrix_char_get(const gsl_matrix_char * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_char_set(gsl_matrix_char * m, const size_t i, const size_t j, const char x); +INLINE_DECL char * gsl_matrix_char_ptr(gsl_matrix_char * m, const size_t i, const size_t j); +INLINE_DECL const char * gsl_matrix_char_const_ptr(const gsl_matrix_char * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +char +gsl_matrix_char_get(const gsl_matrix_char * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_char_set(gsl_matrix_char * m, const size_t i, const size_t j, const char x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +char * +gsl_matrix_char_ptr(gsl_matrix_char * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (char *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const char * +gsl_matrix_char_const_ptr(const gsl_matrix_char * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const char *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_double.h new file mode 100644 index 0000000..b050efc --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_double.h @@ -0,0 +1,358 @@ +/* matrix/gsl_matrix_complex_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_COMPLEX_DOUBLE_H__ +#define __GSL_MATRIX_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + double * data; + gsl_block_complex * block; + int owner; +} gsl_matrix_complex ; + +typedef struct +{ + gsl_matrix_complex matrix; +} _gsl_matrix_complex_view; + +typedef _gsl_matrix_complex_view gsl_matrix_complex_view; + +typedef struct +{ + gsl_matrix_complex matrix; +} _gsl_matrix_complex_const_view; + +typedef const _gsl_matrix_complex_const_view gsl_matrix_complex_const_view; + + +/* Allocation */ + +gsl_matrix_complex * +gsl_matrix_complex_alloc (const size_t n1, const size_t n2); + +gsl_matrix_complex * +gsl_matrix_complex_calloc (const size_t n1, const size_t n2); + +gsl_matrix_complex * +gsl_matrix_complex_alloc_from_block (gsl_block_complex * b, + const size_t offset, + const size_t n1, const size_t n2, const size_t d2); + +gsl_matrix_complex * +gsl_matrix_complex_alloc_from_matrix (gsl_matrix_complex * b, + const size_t k1, const size_t k2, + const size_t n1, const size_t n2); + +gsl_vector_complex * +gsl_vector_complex_alloc_row_from_matrix (gsl_matrix_complex * m, + const size_t i); + +gsl_vector_complex * +gsl_vector_complex_alloc_col_from_matrix (gsl_matrix_complex * m, + const size_t j); + +void gsl_matrix_complex_free (gsl_matrix_complex * m); + +/* Views */ + +_gsl_matrix_complex_view +gsl_matrix_complex_submatrix (gsl_matrix_complex * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_view +gsl_matrix_complex_row (gsl_matrix_complex * m, const size_t i); + +_gsl_vector_complex_view +gsl_matrix_complex_column (gsl_matrix_complex * m, const size_t j); + +_gsl_vector_complex_view +gsl_matrix_complex_diagonal (gsl_matrix_complex * m); + +_gsl_vector_complex_view +gsl_matrix_complex_subdiagonal (gsl_matrix_complex * m, const size_t k); + +_gsl_vector_complex_view +gsl_matrix_complex_superdiagonal (gsl_matrix_complex * m, const size_t k); + +_gsl_vector_complex_view +gsl_matrix_complex_subrow (gsl_matrix_complex * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_view +gsl_matrix_complex_subcolumn (gsl_matrix_complex * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_view +gsl_matrix_complex_view_array (double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_view +gsl_matrix_complex_view_array_with_tda (double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_view +gsl_matrix_complex_view_vector (gsl_vector_complex * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_view +gsl_matrix_complex_view_vector_with_tda (gsl_vector_complex * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_complex_const_view +gsl_matrix_complex_const_submatrix (const gsl_matrix_complex * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_row (const gsl_matrix_complex * m, + const size_t i); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_column (const gsl_matrix_complex * m, + const size_t j); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_diagonal (const gsl_matrix_complex * m); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_subdiagonal (const gsl_matrix_complex * m, + const size_t k); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_superdiagonal (const gsl_matrix_complex * m, + const size_t k); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_subrow (const gsl_matrix_complex * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_const_view +gsl_matrix_complex_const_subcolumn (const gsl_matrix_complex * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_const_view +gsl_matrix_complex_const_view_array (const double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_const_view +gsl_matrix_complex_const_view_array_with_tda (const double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_const_view +gsl_matrix_complex_const_view_vector (const gsl_vector_complex * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_const_view +gsl_matrix_complex_const_view_vector_with_tda (const gsl_vector_complex * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_complex_set_zero (gsl_matrix_complex * m); +void gsl_matrix_complex_set_identity (gsl_matrix_complex * m); +void gsl_matrix_complex_set_all (gsl_matrix_complex * m, gsl_complex x); + +int gsl_matrix_complex_fread (FILE * stream, gsl_matrix_complex * m) ; +int gsl_matrix_complex_fwrite (FILE * stream, const gsl_matrix_complex * m) ; +int gsl_matrix_complex_fscanf (FILE * stream, gsl_matrix_complex * m); +int gsl_matrix_complex_fprintf (FILE * stream, const gsl_matrix_complex * m, const char * format); + +int gsl_matrix_complex_memcpy(gsl_matrix_complex * dest, const gsl_matrix_complex * src); +int gsl_matrix_complex_swap(gsl_matrix_complex * m1, gsl_matrix_complex * m2); +int gsl_matrix_complex_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_complex * dest, const gsl_matrix_complex * src); + +int gsl_matrix_complex_swap_rows(gsl_matrix_complex * m, const size_t i, const size_t j); +int gsl_matrix_complex_swap_columns(gsl_matrix_complex * m, const size_t i, const size_t j); +int gsl_matrix_complex_swap_rowcol(gsl_matrix_complex * m, const size_t i, const size_t j); + +int gsl_matrix_complex_transpose (gsl_matrix_complex * m); +int gsl_matrix_complex_transpose_memcpy (gsl_matrix_complex * dest, const gsl_matrix_complex * src); +int gsl_matrix_complex_transpose_tricpy(CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_complex * dest, const gsl_matrix_complex * src); + +int gsl_matrix_complex_conjtrans_memcpy (gsl_matrix_complex * dest, const gsl_matrix_complex * src); + +int gsl_matrix_complex_equal (const gsl_matrix_complex * a, const gsl_matrix_complex * b); + +int gsl_matrix_complex_isnull (const gsl_matrix_complex * m); +int gsl_matrix_complex_ispos (const gsl_matrix_complex * m); +int gsl_matrix_complex_isneg (const gsl_matrix_complex * m); +int gsl_matrix_complex_isnonneg (const gsl_matrix_complex * m); + +int gsl_matrix_complex_add (gsl_matrix_complex * a, const gsl_matrix_complex * b); +int gsl_matrix_complex_sub (gsl_matrix_complex * a, const gsl_matrix_complex * b); +int gsl_matrix_complex_mul_elements (gsl_matrix_complex * a, const gsl_matrix_complex * b); +int gsl_matrix_complex_div_elements (gsl_matrix_complex * a, const gsl_matrix_complex * b); +int gsl_matrix_complex_scale (gsl_matrix_complex * a, const gsl_complex x); +int gsl_matrix_complex_scale_rows (gsl_matrix_complex * a, const gsl_vector_complex * x); +int gsl_matrix_complex_scale_columns (gsl_matrix_complex * a, const gsl_vector_complex * x); +int gsl_matrix_complex_add_constant (gsl_matrix_complex * a, const gsl_complex x); +int gsl_matrix_complex_add_diagonal (gsl_matrix_complex * a, const gsl_complex x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_complex_get_row(gsl_vector_complex * v, const gsl_matrix_complex * m, const size_t i); +int gsl_matrix_complex_get_col(gsl_vector_complex * v, const gsl_matrix_complex * m, const size_t j); +int gsl_matrix_complex_set_row(gsl_matrix_complex * m, const size_t i, const gsl_vector_complex * v); +int gsl_matrix_complex_set_col(gsl_matrix_complex * m, const size_t j, const gsl_vector_complex * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL gsl_complex gsl_matrix_complex_get(const gsl_matrix_complex * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_complex_set(gsl_matrix_complex * m, const size_t i, const size_t j, const gsl_complex x); + +INLINE_DECL gsl_complex * gsl_matrix_complex_ptr(gsl_matrix_complex * m, const size_t i, const size_t j); +INLINE_DECL const gsl_complex * gsl_matrix_complex_const_ptr(const gsl_matrix_complex * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex +gsl_matrix_complex_get(const gsl_matrix_complex * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + gsl_complex zero = {{0,0}}; + + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; + } + } +#endif + return *(gsl_complex *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +void +gsl_matrix_complex_set(gsl_matrix_complex * m, + const size_t i, const size_t j, const gsl_complex x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + *(gsl_complex *)(m->data + 2*(i * m->tda + j)) = x ; +} + +INLINE_FUN +gsl_complex * +gsl_matrix_complex_ptr(gsl_matrix_complex * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (gsl_complex *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +const gsl_complex * +gsl_matrix_complex_const_ptr(const gsl_matrix_complex * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const gsl_complex *)(m->data + 2*(i * m->tda + j)) ; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_MATRIX_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_float.h new file mode 100644 index 0000000..ee69088 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_float.h @@ -0,0 +1,358 @@ +/* matrix/gsl_matrix_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_COMPLEX_FLOAT_H__ +#define __GSL_MATRIX_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + float * data; + gsl_block_complex_float * block; + int owner; +} gsl_matrix_complex_float ; + +typedef struct +{ + gsl_matrix_complex_float matrix; +} _gsl_matrix_complex_float_view; + +typedef _gsl_matrix_complex_float_view gsl_matrix_complex_float_view; + +typedef struct +{ + gsl_matrix_complex_float matrix; +} _gsl_matrix_complex_float_const_view; + +typedef const _gsl_matrix_complex_float_const_view gsl_matrix_complex_float_const_view; + + +/* Allocation */ + +gsl_matrix_complex_float * +gsl_matrix_complex_float_alloc (const size_t n1, const size_t n2); + +gsl_matrix_complex_float * +gsl_matrix_complex_float_calloc (const size_t n1, const size_t n2); + +gsl_matrix_complex_float * +gsl_matrix_complex_float_alloc_from_block (gsl_block_complex_float * b, + const size_t offset, + const size_t n1, const size_t n2, const size_t d2); + +gsl_matrix_complex_float * +gsl_matrix_complex_float_alloc_from_matrix (gsl_matrix_complex_float * b, + const size_t k1, const size_t k2, + const size_t n1, const size_t n2); + +gsl_vector_complex_float * +gsl_vector_complex_float_alloc_row_from_matrix (gsl_matrix_complex_float * m, + const size_t i); + +gsl_vector_complex_float * +gsl_vector_complex_float_alloc_col_from_matrix (gsl_matrix_complex_float * m, + const size_t j); + +void gsl_matrix_complex_float_free (gsl_matrix_complex_float * m); + +/* Views */ + +_gsl_matrix_complex_float_view +gsl_matrix_complex_float_submatrix (gsl_matrix_complex_float * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_row (gsl_matrix_complex_float * m, const size_t i); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_column (gsl_matrix_complex_float * m, const size_t j); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_diagonal (gsl_matrix_complex_float * m); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_subdiagonal (gsl_matrix_complex_float * m, const size_t k); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_superdiagonal (gsl_matrix_complex_float * m, const size_t k); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_subrow (gsl_matrix_complex_float * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_float_view +gsl_matrix_complex_float_subcolumn (gsl_matrix_complex_float * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_float_view +gsl_matrix_complex_float_view_array (float * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_float_view +gsl_matrix_complex_float_view_array_with_tda (float * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_float_view +gsl_matrix_complex_float_view_vector (gsl_vector_complex_float * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_float_view +gsl_matrix_complex_float_view_vector_with_tda (gsl_vector_complex_float * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_complex_float_const_view +gsl_matrix_complex_float_const_submatrix (const gsl_matrix_complex_float * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_row (const gsl_matrix_complex_float * m, + const size_t i); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_column (const gsl_matrix_complex_float * m, + const size_t j); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_diagonal (const gsl_matrix_complex_float * m); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_subdiagonal (const gsl_matrix_complex_float * m, + const size_t k); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_superdiagonal (const gsl_matrix_complex_float * m, + const size_t k); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_subrow (const gsl_matrix_complex_float * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_float_const_view +gsl_matrix_complex_float_const_subcolumn (const gsl_matrix_complex_float * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_float_const_view +gsl_matrix_complex_float_const_view_array (const float * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_float_const_view +gsl_matrix_complex_float_const_view_array_with_tda (const float * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_float_const_view +gsl_matrix_complex_float_const_view_vector (const gsl_vector_complex_float * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_float_const_view +gsl_matrix_complex_float_const_view_vector_with_tda (const gsl_vector_complex_float * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_complex_float_set_zero (gsl_matrix_complex_float * m); +void gsl_matrix_complex_float_set_identity (gsl_matrix_complex_float * m); +void gsl_matrix_complex_float_set_all (gsl_matrix_complex_float * m, gsl_complex_float x); + +int gsl_matrix_complex_float_fread (FILE * stream, gsl_matrix_complex_float * m) ; +int gsl_matrix_complex_float_fwrite (FILE * stream, const gsl_matrix_complex_float * m) ; +int gsl_matrix_complex_float_fscanf (FILE * stream, gsl_matrix_complex_float * m); +int gsl_matrix_complex_float_fprintf (FILE * stream, const gsl_matrix_complex_float * m, const char * format); + +int gsl_matrix_complex_float_memcpy(gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); +int gsl_matrix_complex_float_swap(gsl_matrix_complex_float * m1, gsl_matrix_complex_float * m2); +int gsl_matrix_complex_float_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); + +int gsl_matrix_complex_float_swap_rows(gsl_matrix_complex_float * m, const size_t i, const size_t j); +int gsl_matrix_complex_float_swap_columns(gsl_matrix_complex_float * m, const size_t i, const size_t j); +int gsl_matrix_complex_float_swap_rowcol(gsl_matrix_complex_float * m, const size_t i, const size_t j); + +int gsl_matrix_complex_float_transpose (gsl_matrix_complex_float * m); +int gsl_matrix_complex_float_transpose_memcpy (gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); +int gsl_matrix_complex_float_transpose_tricpy(CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); + +int gsl_matrix_complex_float_conjtrans_memcpy (gsl_matrix_complex_float * dest, const gsl_matrix_complex_float * src); + +int gsl_matrix_complex_float_equal (const gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); + +int gsl_matrix_complex_float_isnull (const gsl_matrix_complex_float * m); +int gsl_matrix_complex_float_ispos (const gsl_matrix_complex_float * m); +int gsl_matrix_complex_float_isneg (const gsl_matrix_complex_float * m); +int gsl_matrix_complex_float_isnonneg (const gsl_matrix_complex_float * m); + +int gsl_matrix_complex_float_add (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); +int gsl_matrix_complex_float_sub (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); +int gsl_matrix_complex_float_mul_elements (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); +int gsl_matrix_complex_float_div_elements (gsl_matrix_complex_float * a, const gsl_matrix_complex_float * b); +int gsl_matrix_complex_float_scale (gsl_matrix_complex_float * a, const gsl_complex_float x); +int gsl_matrix_complex_float_scale_rows (gsl_matrix_complex_float * a, const gsl_vector_complex_float * x); +int gsl_matrix_complex_float_scale_columns (gsl_matrix_complex_float * a, const gsl_vector_complex_float * x); +int gsl_matrix_complex_float_add_constant (gsl_matrix_complex_float * a, const gsl_complex_float x); +int gsl_matrix_complex_float_add_diagonal (gsl_matrix_complex_float * a, const gsl_complex_float x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_complex_float_get_row(gsl_vector_complex_float * v, const gsl_matrix_complex_float * m, const size_t i); +int gsl_matrix_complex_float_get_col(gsl_vector_complex_float * v, const gsl_matrix_complex_float * m, const size_t j); +int gsl_matrix_complex_float_set_row(gsl_matrix_complex_float * m, const size_t i, const gsl_vector_complex_float * v); +int gsl_matrix_complex_float_set_col(gsl_matrix_complex_float * m, const size_t j, const gsl_vector_complex_float * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL gsl_complex_float gsl_matrix_complex_float_get(const gsl_matrix_complex_float * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_complex_float_set(gsl_matrix_complex_float * m, const size_t i, const size_t j, const gsl_complex_float x); + +INLINE_DECL gsl_complex_float * gsl_matrix_complex_float_ptr(gsl_matrix_complex_float * m, const size_t i, const size_t j); +INLINE_DECL const gsl_complex_float * gsl_matrix_complex_float_const_ptr(const gsl_matrix_complex_float * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex_float +gsl_matrix_complex_float_get(const gsl_matrix_complex_float * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + gsl_complex_float zero = {{0,0}}; + + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; + } + } +#endif + return *(gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +void +gsl_matrix_complex_float_set(gsl_matrix_complex_float * m, + const size_t i, const size_t j, const gsl_complex_float x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + *(gsl_complex_float *)(m->data + 2*(i * m->tda + j)) = x ; +} + +INLINE_FUN +gsl_complex_float * +gsl_matrix_complex_float_ptr(gsl_matrix_complex_float * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +const gsl_complex_float * +gsl_matrix_complex_float_const_ptr(const gsl_matrix_complex_float * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const gsl_complex_float *)(m->data + 2*(i * m->tda + j)) ; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_MATRIX_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_long_double.h new file mode 100644 index 0000000..79be094 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_complex_long_double.h @@ -0,0 +1,358 @@ +/* matrix/gsl_matrix_complex_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + long double * data; + gsl_block_complex_long_double * block; + int owner; +} gsl_matrix_complex_long_double ; + +typedef struct +{ + gsl_matrix_complex_long_double matrix; +} _gsl_matrix_complex_long_double_view; + +typedef _gsl_matrix_complex_long_double_view gsl_matrix_complex_long_double_view; + +typedef struct +{ + gsl_matrix_complex_long_double matrix; +} _gsl_matrix_complex_long_double_const_view; + +typedef const _gsl_matrix_complex_long_double_const_view gsl_matrix_complex_long_double_const_view; + + +/* Allocation */ + +gsl_matrix_complex_long_double * +gsl_matrix_complex_long_double_alloc (const size_t n1, const size_t n2); + +gsl_matrix_complex_long_double * +gsl_matrix_complex_long_double_calloc (const size_t n1, const size_t n2); + +gsl_matrix_complex_long_double * +gsl_matrix_complex_long_double_alloc_from_block (gsl_block_complex_long_double * b, + const size_t offset, + const size_t n1, const size_t n2, const size_t d2); + +gsl_matrix_complex_long_double * +gsl_matrix_complex_long_double_alloc_from_matrix (gsl_matrix_complex_long_double * b, + const size_t k1, const size_t k2, + const size_t n1, const size_t n2); + +gsl_vector_complex_long_double * +gsl_vector_complex_long_double_alloc_row_from_matrix (gsl_matrix_complex_long_double * m, + const size_t i); + +gsl_vector_complex_long_double * +gsl_vector_complex_long_double_alloc_col_from_matrix (gsl_matrix_complex_long_double * m, + const size_t j); + +void gsl_matrix_complex_long_double_free (gsl_matrix_complex_long_double * m); + +/* Views */ + +_gsl_matrix_complex_long_double_view +gsl_matrix_complex_long_double_submatrix (gsl_matrix_complex_long_double * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_row (gsl_matrix_complex_long_double * m, const size_t i); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_column (gsl_matrix_complex_long_double * m, const size_t j); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_diagonal (gsl_matrix_complex_long_double * m); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_subdiagonal (gsl_matrix_complex_long_double * m, const size_t k); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_superdiagonal (gsl_matrix_complex_long_double * m, const size_t k); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_subrow (gsl_matrix_complex_long_double * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_long_double_view +gsl_matrix_complex_long_double_subcolumn (gsl_matrix_complex_long_double * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_long_double_view +gsl_matrix_complex_long_double_view_array (long double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_long_double_view +gsl_matrix_complex_long_double_view_array_with_tda (long double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_long_double_view +gsl_matrix_complex_long_double_view_vector (gsl_vector_complex_long_double * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_long_double_view +gsl_matrix_complex_long_double_view_vector_with_tda (gsl_vector_complex_long_double * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_complex_long_double_const_view +gsl_matrix_complex_long_double_const_submatrix (const gsl_matrix_complex_long_double * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_row (const gsl_matrix_complex_long_double * m, + const size_t i); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_column (const gsl_matrix_complex_long_double * m, + const size_t j); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_diagonal (const gsl_matrix_complex_long_double * m); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_subdiagonal (const gsl_matrix_complex_long_double * m, + const size_t k); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_superdiagonal (const gsl_matrix_complex_long_double * m, + const size_t k); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_subrow (const gsl_matrix_complex_long_double * m, + const size_t i, const size_t offset, + const size_t n); + +_gsl_vector_complex_long_double_const_view +gsl_matrix_complex_long_double_const_subcolumn (const gsl_matrix_complex_long_double * m, + const size_t j, const size_t offset, + const size_t n); + +_gsl_matrix_complex_long_double_const_view +gsl_matrix_complex_long_double_const_view_array (const long double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_long_double_const_view +gsl_matrix_complex_long_double_const_view_array_with_tda (const long double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_complex_long_double_const_view +gsl_matrix_complex_long_double_const_view_vector (const gsl_vector_complex_long_double * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_complex_long_double_const_view +gsl_matrix_complex_long_double_const_view_vector_with_tda (const gsl_vector_complex_long_double * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_complex_long_double_set_zero (gsl_matrix_complex_long_double * m); +void gsl_matrix_complex_long_double_set_identity (gsl_matrix_complex_long_double * m); +void gsl_matrix_complex_long_double_set_all (gsl_matrix_complex_long_double * m, gsl_complex_long_double x); + +int gsl_matrix_complex_long_double_fread (FILE * stream, gsl_matrix_complex_long_double * m) ; +int gsl_matrix_complex_long_double_fwrite (FILE * stream, const gsl_matrix_complex_long_double * m) ; +int gsl_matrix_complex_long_double_fscanf (FILE * stream, gsl_matrix_complex_long_double * m); +int gsl_matrix_complex_long_double_fprintf (FILE * stream, const gsl_matrix_complex_long_double * m, const char * format); + +int gsl_matrix_complex_long_double_memcpy(gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); +int gsl_matrix_complex_long_double_swap(gsl_matrix_complex_long_double * m1, gsl_matrix_complex_long_double * m2); +int gsl_matrix_complex_long_double_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); + +int gsl_matrix_complex_long_double_swap_rows(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); +int gsl_matrix_complex_long_double_swap_columns(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); +int gsl_matrix_complex_long_double_swap_rowcol(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); + +int gsl_matrix_complex_long_double_transpose (gsl_matrix_complex_long_double * m); +int gsl_matrix_complex_long_double_transpose_memcpy (gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); +int gsl_matrix_complex_long_double_transpose_tricpy(CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); + +int gsl_matrix_complex_long_double_conjtrans_memcpy (gsl_matrix_complex_long_double * dest, const gsl_matrix_complex_long_double * src); + +int gsl_matrix_complex_long_double_equal (const gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); + +int gsl_matrix_complex_long_double_isnull (const gsl_matrix_complex_long_double * m); +int gsl_matrix_complex_long_double_ispos (const gsl_matrix_complex_long_double * m); +int gsl_matrix_complex_long_double_isneg (const gsl_matrix_complex_long_double * m); +int gsl_matrix_complex_long_double_isnonneg (const gsl_matrix_complex_long_double * m); + +int gsl_matrix_complex_long_double_add (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); +int gsl_matrix_complex_long_double_sub (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); +int gsl_matrix_complex_long_double_mul_elements (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); +int gsl_matrix_complex_long_double_div_elements (gsl_matrix_complex_long_double * a, const gsl_matrix_complex_long_double * b); +int gsl_matrix_complex_long_double_scale (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); +int gsl_matrix_complex_long_double_scale_rows (gsl_matrix_complex_long_double * a, const gsl_vector_complex_long_double * x); +int gsl_matrix_complex_long_double_scale_columns (gsl_matrix_complex_long_double * a, const gsl_vector_complex_long_double * x); +int gsl_matrix_complex_long_double_add_constant (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); +int gsl_matrix_complex_long_double_add_diagonal (gsl_matrix_complex_long_double * a, const gsl_complex_long_double x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_complex_long_double_get_row(gsl_vector_complex_long_double * v, const gsl_matrix_complex_long_double * m, const size_t i); +int gsl_matrix_complex_long_double_get_col(gsl_vector_complex_long_double * v, const gsl_matrix_complex_long_double * m, const size_t j); +int gsl_matrix_complex_long_double_set_row(gsl_matrix_complex_long_double * m, const size_t i, const gsl_vector_complex_long_double * v); +int gsl_matrix_complex_long_double_set_col(gsl_matrix_complex_long_double * m, const size_t j, const gsl_vector_complex_long_double * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL gsl_complex_long_double gsl_matrix_complex_long_double_get(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_complex_long_double_set(gsl_matrix_complex_long_double * m, const size_t i, const size_t j, const gsl_complex_long_double x); + +INLINE_DECL gsl_complex_long_double * gsl_matrix_complex_long_double_ptr(gsl_matrix_complex_long_double * m, const size_t i, const size_t j); +INLINE_DECL const gsl_complex_long_double * gsl_matrix_complex_long_double_const_ptr(const gsl_matrix_complex_long_double * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex_long_double +gsl_matrix_complex_long_double_get(const gsl_matrix_complex_long_double * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + gsl_complex_long_double zero = {{0,0}}; + + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, zero) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, zero) ; + } + } +#endif + return *(gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +void +gsl_matrix_complex_long_double_set(gsl_matrix_complex_long_double * m, + const size_t i, const size_t j, const gsl_complex_long_double x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + *(gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) = x ; +} + +INLINE_FUN +gsl_complex_long_double * +gsl_matrix_complex_long_double_ptr(gsl_matrix_complex_long_double * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; +} + +INLINE_FUN +const gsl_complex_long_double * +gsl_matrix_complex_long_double_const_ptr(const gsl_matrix_complex_long_double * m, + const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const gsl_complex_long_double *)(m->data + 2*(i * m->tda + j)) ; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_MATRIX_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_double.h new file mode 100644 index 0000000..c54fa59 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_double.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_DOUBLE_H__ +#define __GSL_MATRIX_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + double * data; + gsl_block * block; + int owner; +} gsl_matrix; + +typedef struct +{ + gsl_matrix matrix; +} _gsl_matrix_view; + +typedef _gsl_matrix_view gsl_matrix_view; + +typedef struct +{ + gsl_matrix matrix; +} _gsl_matrix_const_view; + +typedef const _gsl_matrix_const_view gsl_matrix_const_view; + +/* Allocation */ + +gsl_matrix * +gsl_matrix_alloc (const size_t n1, const size_t n2); + +gsl_matrix * +gsl_matrix_calloc (const size_t n1, const size_t n2); + +gsl_matrix * +gsl_matrix_alloc_from_block (gsl_block * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix * +gsl_matrix_alloc_from_matrix (gsl_matrix * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector * +gsl_vector_alloc_row_from_matrix (gsl_matrix * m, + const size_t i); + +gsl_vector * +gsl_vector_alloc_col_from_matrix (gsl_matrix * m, + const size_t j); + +void gsl_matrix_free (gsl_matrix * m); + +/* Views */ + +_gsl_matrix_view +gsl_matrix_submatrix (gsl_matrix * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_view +gsl_matrix_row (gsl_matrix * m, const size_t i); + +_gsl_vector_view +gsl_matrix_column (gsl_matrix * m, const size_t j); + +_gsl_vector_view +gsl_matrix_diagonal (gsl_matrix * m); + +_gsl_vector_view +gsl_matrix_subdiagonal (gsl_matrix * m, const size_t k); + +_gsl_vector_view +gsl_matrix_superdiagonal (gsl_matrix * m, const size_t k); + +_gsl_vector_view +gsl_matrix_subrow (gsl_matrix * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_view +gsl_matrix_subcolumn (gsl_matrix * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_view +gsl_matrix_view_array (double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_view +gsl_matrix_view_array_with_tda (double * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_view +gsl_matrix_view_vector (gsl_vector * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_view +gsl_matrix_view_vector_with_tda (gsl_vector * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_const_view +gsl_matrix_const_submatrix (const gsl_matrix * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_const_view +gsl_matrix_const_row (const gsl_matrix * m, + const size_t i); + +_gsl_vector_const_view +gsl_matrix_const_column (const gsl_matrix * m, + const size_t j); + +_gsl_vector_const_view +gsl_matrix_const_diagonal (const gsl_matrix * m); + +_gsl_vector_const_view +gsl_matrix_const_subdiagonal (const gsl_matrix * m, + const size_t k); + +_gsl_vector_const_view +gsl_matrix_const_superdiagonal (const gsl_matrix * m, + const size_t k); + +_gsl_vector_const_view +gsl_matrix_const_subrow (const gsl_matrix * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_const_view +gsl_matrix_const_subcolumn (const gsl_matrix * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_const_view +gsl_matrix_const_view_array (const double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_const_view +gsl_matrix_const_view_array_with_tda (const double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_const_view +gsl_matrix_const_view_vector (const gsl_vector * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_const_view +gsl_matrix_const_view_vector_with_tda (const gsl_vector * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_set_zero (gsl_matrix * m); +void gsl_matrix_set_identity (gsl_matrix * m); +void gsl_matrix_set_all (gsl_matrix * m, double x); + +int gsl_matrix_fread (FILE * stream, gsl_matrix * m) ; +int gsl_matrix_fwrite (FILE * stream, const gsl_matrix * m) ; +int gsl_matrix_fscanf (FILE * stream, gsl_matrix * m); +int gsl_matrix_fprintf (FILE * stream, const gsl_matrix * m, const char * format); + +int gsl_matrix_memcpy(gsl_matrix * dest, const gsl_matrix * src); +int gsl_matrix_swap(gsl_matrix * m1, gsl_matrix * m2); +int gsl_matrix_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix * dest, const gsl_matrix * src); + +int gsl_matrix_swap_rows(gsl_matrix * m, const size_t i, const size_t j); +int gsl_matrix_swap_columns(gsl_matrix * m, const size_t i, const size_t j); +int gsl_matrix_swap_rowcol(gsl_matrix * m, const size_t i, const size_t j); +int gsl_matrix_transpose (gsl_matrix * m); +int gsl_matrix_transpose_memcpy (gsl_matrix * dest, const gsl_matrix * src); +int gsl_matrix_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix * dest, const gsl_matrix * src); + +double gsl_matrix_max (const gsl_matrix * m); +double gsl_matrix_min (const gsl_matrix * m); +void gsl_matrix_minmax (const gsl_matrix * m, double * min_out, double * max_out); + +void gsl_matrix_max_index (const gsl_matrix * m, size_t * imax, size_t *jmax); +void gsl_matrix_min_index (const gsl_matrix * m, size_t * imin, size_t *jmin); +void gsl_matrix_minmax_index (const gsl_matrix * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_equal (const gsl_matrix * a, const gsl_matrix * b); + +int gsl_matrix_isnull (const gsl_matrix * m); +int gsl_matrix_ispos (const gsl_matrix * m); +int gsl_matrix_isneg (const gsl_matrix * m); +int gsl_matrix_isnonneg (const gsl_matrix * m); + +double gsl_matrix_norm1 (const gsl_matrix * m); + +int gsl_matrix_add (gsl_matrix * a, const gsl_matrix * b); +int gsl_matrix_sub (gsl_matrix * a, const gsl_matrix * b); +int gsl_matrix_mul_elements (gsl_matrix * a, const gsl_matrix * b); +int gsl_matrix_div_elements (gsl_matrix * a, const gsl_matrix * b); +int gsl_matrix_scale (gsl_matrix * a, const double x); +int gsl_matrix_scale_rows (gsl_matrix * a, const gsl_vector * x); +int gsl_matrix_scale_columns (gsl_matrix * a, const gsl_vector * x); +int gsl_matrix_add_constant (gsl_matrix * a, const double x); +int gsl_matrix_add_diagonal (gsl_matrix * a, const double x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_get_row(gsl_vector * v, const gsl_matrix * m, const size_t i); +int gsl_matrix_get_col(gsl_vector * v, const gsl_matrix * m, const size_t j); +int gsl_matrix_set_row(gsl_matrix * m, const size_t i, const gsl_vector * v); +int gsl_matrix_set_col(gsl_matrix * m, const size_t j, const gsl_vector * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL double gsl_matrix_get(const gsl_matrix * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_set(gsl_matrix * m, const size_t i, const size_t j, const double x); +INLINE_DECL double * gsl_matrix_ptr(gsl_matrix * m, const size_t i, const size_t j); +INLINE_DECL const double * gsl_matrix_const_ptr(const gsl_matrix * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +double +gsl_matrix_get(const gsl_matrix * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_set(gsl_matrix * m, const size_t i, const size_t j, const double x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +double * +gsl_matrix_ptr(gsl_matrix * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (double *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const double * +gsl_matrix_const_ptr(const gsl_matrix * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const double *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_float.h new file mode 100644 index 0000000..356bf8b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_float.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_FLOAT_H__ +#define __GSL_MATRIX_FLOAT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + float * data; + gsl_block_float * block; + int owner; +} gsl_matrix_float; + +typedef struct +{ + gsl_matrix_float matrix; +} _gsl_matrix_float_view; + +typedef _gsl_matrix_float_view gsl_matrix_float_view; + +typedef struct +{ + gsl_matrix_float matrix; +} _gsl_matrix_float_const_view; + +typedef const _gsl_matrix_float_const_view gsl_matrix_float_const_view; + +/* Allocation */ + +gsl_matrix_float * +gsl_matrix_float_alloc (const size_t n1, const size_t n2); + +gsl_matrix_float * +gsl_matrix_float_calloc (const size_t n1, const size_t n2); + +gsl_matrix_float * +gsl_matrix_float_alloc_from_block (gsl_block_float * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_float * +gsl_matrix_float_alloc_from_matrix (gsl_matrix_float * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_float * +gsl_vector_float_alloc_row_from_matrix (gsl_matrix_float * m, + const size_t i); + +gsl_vector_float * +gsl_vector_float_alloc_col_from_matrix (gsl_matrix_float * m, + const size_t j); + +void gsl_matrix_float_free (gsl_matrix_float * m); + +/* Views */ + +_gsl_matrix_float_view +gsl_matrix_float_submatrix (gsl_matrix_float * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_float_view +gsl_matrix_float_row (gsl_matrix_float * m, const size_t i); + +_gsl_vector_float_view +gsl_matrix_float_column (gsl_matrix_float * m, const size_t j); + +_gsl_vector_float_view +gsl_matrix_float_diagonal (gsl_matrix_float * m); + +_gsl_vector_float_view +gsl_matrix_float_subdiagonal (gsl_matrix_float * m, const size_t k); + +_gsl_vector_float_view +gsl_matrix_float_superdiagonal (gsl_matrix_float * m, const size_t k); + +_gsl_vector_float_view +gsl_matrix_float_subrow (gsl_matrix_float * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_float_view +gsl_matrix_float_subcolumn (gsl_matrix_float * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_float_view +gsl_matrix_float_view_array (float * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_float_view +gsl_matrix_float_view_array_with_tda (float * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_float_view +gsl_matrix_float_view_vector (gsl_vector_float * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_float_view +gsl_matrix_float_view_vector_with_tda (gsl_vector_float * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_float_const_view +gsl_matrix_float_const_submatrix (const gsl_matrix_float * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_float_const_view +gsl_matrix_float_const_row (const gsl_matrix_float * m, + const size_t i); + +_gsl_vector_float_const_view +gsl_matrix_float_const_column (const gsl_matrix_float * m, + const size_t j); + +_gsl_vector_float_const_view +gsl_matrix_float_const_diagonal (const gsl_matrix_float * m); + +_gsl_vector_float_const_view +gsl_matrix_float_const_subdiagonal (const gsl_matrix_float * m, + const size_t k); + +_gsl_vector_float_const_view +gsl_matrix_float_const_superdiagonal (const gsl_matrix_float * m, + const size_t k); + +_gsl_vector_float_const_view +gsl_matrix_float_const_subrow (const gsl_matrix_float * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_float_const_view +gsl_matrix_float_const_subcolumn (const gsl_matrix_float * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_float_const_view +gsl_matrix_float_const_view_array (const float * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_float_const_view +gsl_matrix_float_const_view_array_with_tda (const float * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_float_const_view +gsl_matrix_float_const_view_vector (const gsl_vector_float * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_float_const_view +gsl_matrix_float_const_view_vector_with_tda (const gsl_vector_float * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_float_set_zero (gsl_matrix_float * m); +void gsl_matrix_float_set_identity (gsl_matrix_float * m); +void gsl_matrix_float_set_all (gsl_matrix_float * m, float x); + +int gsl_matrix_float_fread (FILE * stream, gsl_matrix_float * m) ; +int gsl_matrix_float_fwrite (FILE * stream, const gsl_matrix_float * m) ; +int gsl_matrix_float_fscanf (FILE * stream, gsl_matrix_float * m); +int gsl_matrix_float_fprintf (FILE * stream, const gsl_matrix_float * m, const char * format); + +int gsl_matrix_float_memcpy(gsl_matrix_float * dest, const gsl_matrix_float * src); +int gsl_matrix_float_swap(gsl_matrix_float * m1, gsl_matrix_float * m2); +int gsl_matrix_float_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_float * dest, const gsl_matrix_float * src); + +int gsl_matrix_float_swap_rows(gsl_matrix_float * m, const size_t i, const size_t j); +int gsl_matrix_float_swap_columns(gsl_matrix_float * m, const size_t i, const size_t j); +int gsl_matrix_float_swap_rowcol(gsl_matrix_float * m, const size_t i, const size_t j); +int gsl_matrix_float_transpose (gsl_matrix_float * m); +int gsl_matrix_float_transpose_memcpy (gsl_matrix_float * dest, const gsl_matrix_float * src); +int gsl_matrix_float_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_float * dest, const gsl_matrix_float * src); + +float gsl_matrix_float_max (const gsl_matrix_float * m); +float gsl_matrix_float_min (const gsl_matrix_float * m); +void gsl_matrix_float_minmax (const gsl_matrix_float * m, float * min_out, float * max_out); + +void gsl_matrix_float_max_index (const gsl_matrix_float * m, size_t * imax, size_t *jmax); +void gsl_matrix_float_min_index (const gsl_matrix_float * m, size_t * imin, size_t *jmin); +void gsl_matrix_float_minmax_index (const gsl_matrix_float * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_float_equal (const gsl_matrix_float * a, const gsl_matrix_float * b); + +int gsl_matrix_float_isnull (const gsl_matrix_float * m); +int gsl_matrix_float_ispos (const gsl_matrix_float * m); +int gsl_matrix_float_isneg (const gsl_matrix_float * m); +int gsl_matrix_float_isnonneg (const gsl_matrix_float * m); + +float gsl_matrix_float_norm1 (const gsl_matrix_float * m); + +int gsl_matrix_float_add (gsl_matrix_float * a, const gsl_matrix_float * b); +int gsl_matrix_float_sub (gsl_matrix_float * a, const gsl_matrix_float * b); +int gsl_matrix_float_mul_elements (gsl_matrix_float * a, const gsl_matrix_float * b); +int gsl_matrix_float_div_elements (gsl_matrix_float * a, const gsl_matrix_float * b); +int gsl_matrix_float_scale (gsl_matrix_float * a, const float x); +int gsl_matrix_float_scale_rows (gsl_matrix_float * a, const gsl_vector_float * x); +int gsl_matrix_float_scale_columns (gsl_matrix_float * a, const gsl_vector_float * x); +int gsl_matrix_float_add_constant (gsl_matrix_float * a, const float x); +int gsl_matrix_float_add_diagonal (gsl_matrix_float * a, const float x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_float_get_row(gsl_vector_float * v, const gsl_matrix_float * m, const size_t i); +int gsl_matrix_float_get_col(gsl_vector_float * v, const gsl_matrix_float * m, const size_t j); +int gsl_matrix_float_set_row(gsl_matrix_float * m, const size_t i, const gsl_vector_float * v); +int gsl_matrix_float_set_col(gsl_matrix_float * m, const size_t j, const gsl_vector_float * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL float gsl_matrix_float_get(const gsl_matrix_float * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_float_set(gsl_matrix_float * m, const size_t i, const size_t j, const float x); +INLINE_DECL float * gsl_matrix_float_ptr(gsl_matrix_float * m, const size_t i, const size_t j); +INLINE_DECL const float * gsl_matrix_float_const_ptr(const gsl_matrix_float * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +float +gsl_matrix_float_get(const gsl_matrix_float * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_float_set(gsl_matrix_float * m, const size_t i, const size_t j, const float x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +float * +gsl_matrix_float_ptr(gsl_matrix_float * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (float *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const float * +gsl_matrix_float_const_ptr(const gsl_matrix_float * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const float *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_int.h new file mode 100644 index 0000000..78c0002 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_int.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_INT_H__ +#define __GSL_MATRIX_INT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + int * data; + gsl_block_int * block; + int owner; +} gsl_matrix_int; + +typedef struct +{ + gsl_matrix_int matrix; +} _gsl_matrix_int_view; + +typedef _gsl_matrix_int_view gsl_matrix_int_view; + +typedef struct +{ + gsl_matrix_int matrix; +} _gsl_matrix_int_const_view; + +typedef const _gsl_matrix_int_const_view gsl_matrix_int_const_view; + +/* Allocation */ + +gsl_matrix_int * +gsl_matrix_int_alloc (const size_t n1, const size_t n2); + +gsl_matrix_int * +gsl_matrix_int_calloc (const size_t n1, const size_t n2); + +gsl_matrix_int * +gsl_matrix_int_alloc_from_block (gsl_block_int * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_int * +gsl_matrix_int_alloc_from_matrix (gsl_matrix_int * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_int * +gsl_vector_int_alloc_row_from_matrix (gsl_matrix_int * m, + const size_t i); + +gsl_vector_int * +gsl_vector_int_alloc_col_from_matrix (gsl_matrix_int * m, + const size_t j); + +void gsl_matrix_int_free (gsl_matrix_int * m); + +/* Views */ + +_gsl_matrix_int_view +gsl_matrix_int_submatrix (gsl_matrix_int * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_int_view +gsl_matrix_int_row (gsl_matrix_int * m, const size_t i); + +_gsl_vector_int_view +gsl_matrix_int_column (gsl_matrix_int * m, const size_t j); + +_gsl_vector_int_view +gsl_matrix_int_diagonal (gsl_matrix_int * m); + +_gsl_vector_int_view +gsl_matrix_int_subdiagonal (gsl_matrix_int * m, const size_t k); + +_gsl_vector_int_view +gsl_matrix_int_superdiagonal (gsl_matrix_int * m, const size_t k); + +_gsl_vector_int_view +gsl_matrix_int_subrow (gsl_matrix_int * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_int_view +gsl_matrix_int_subcolumn (gsl_matrix_int * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_int_view +gsl_matrix_int_view_array (int * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_int_view +gsl_matrix_int_view_array_with_tda (int * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_int_view +gsl_matrix_int_view_vector (gsl_vector_int * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_int_view +gsl_matrix_int_view_vector_with_tda (gsl_vector_int * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_int_const_view +gsl_matrix_int_const_submatrix (const gsl_matrix_int * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_int_const_view +gsl_matrix_int_const_row (const gsl_matrix_int * m, + const size_t i); + +_gsl_vector_int_const_view +gsl_matrix_int_const_column (const gsl_matrix_int * m, + const size_t j); + +_gsl_vector_int_const_view +gsl_matrix_int_const_diagonal (const gsl_matrix_int * m); + +_gsl_vector_int_const_view +gsl_matrix_int_const_subdiagonal (const gsl_matrix_int * m, + const size_t k); + +_gsl_vector_int_const_view +gsl_matrix_int_const_superdiagonal (const gsl_matrix_int * m, + const size_t k); + +_gsl_vector_int_const_view +gsl_matrix_int_const_subrow (const gsl_matrix_int * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_int_const_view +gsl_matrix_int_const_subcolumn (const gsl_matrix_int * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_int_const_view +gsl_matrix_int_const_view_array (const int * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_int_const_view +gsl_matrix_int_const_view_array_with_tda (const int * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_int_const_view +gsl_matrix_int_const_view_vector (const gsl_vector_int * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_int_const_view +gsl_matrix_int_const_view_vector_with_tda (const gsl_vector_int * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_int_set_zero (gsl_matrix_int * m); +void gsl_matrix_int_set_identity (gsl_matrix_int * m); +void gsl_matrix_int_set_all (gsl_matrix_int * m, int x); + +int gsl_matrix_int_fread (FILE * stream, gsl_matrix_int * m) ; +int gsl_matrix_int_fwrite (FILE * stream, const gsl_matrix_int * m) ; +int gsl_matrix_int_fscanf (FILE * stream, gsl_matrix_int * m); +int gsl_matrix_int_fprintf (FILE * stream, const gsl_matrix_int * m, const char * format); + +int gsl_matrix_int_memcpy(gsl_matrix_int * dest, const gsl_matrix_int * src); +int gsl_matrix_int_swap(gsl_matrix_int * m1, gsl_matrix_int * m2); +int gsl_matrix_int_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_int * dest, const gsl_matrix_int * src); + +int gsl_matrix_int_swap_rows(gsl_matrix_int * m, const size_t i, const size_t j); +int gsl_matrix_int_swap_columns(gsl_matrix_int * m, const size_t i, const size_t j); +int gsl_matrix_int_swap_rowcol(gsl_matrix_int * m, const size_t i, const size_t j); +int gsl_matrix_int_transpose (gsl_matrix_int * m); +int gsl_matrix_int_transpose_memcpy (gsl_matrix_int * dest, const gsl_matrix_int * src); +int gsl_matrix_int_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_int * dest, const gsl_matrix_int * src); + +int gsl_matrix_int_max (const gsl_matrix_int * m); +int gsl_matrix_int_min (const gsl_matrix_int * m); +void gsl_matrix_int_minmax (const gsl_matrix_int * m, int * min_out, int * max_out); + +void gsl_matrix_int_max_index (const gsl_matrix_int * m, size_t * imax, size_t *jmax); +void gsl_matrix_int_min_index (const gsl_matrix_int * m, size_t * imin, size_t *jmin); +void gsl_matrix_int_minmax_index (const gsl_matrix_int * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_int_equal (const gsl_matrix_int * a, const gsl_matrix_int * b); + +int gsl_matrix_int_isnull (const gsl_matrix_int * m); +int gsl_matrix_int_ispos (const gsl_matrix_int * m); +int gsl_matrix_int_isneg (const gsl_matrix_int * m); +int gsl_matrix_int_isnonneg (const gsl_matrix_int * m); + +int gsl_matrix_int_norm1 (const gsl_matrix_int * m); + +int gsl_matrix_int_add (gsl_matrix_int * a, const gsl_matrix_int * b); +int gsl_matrix_int_sub (gsl_matrix_int * a, const gsl_matrix_int * b); +int gsl_matrix_int_mul_elements (gsl_matrix_int * a, const gsl_matrix_int * b); +int gsl_matrix_int_div_elements (gsl_matrix_int * a, const gsl_matrix_int * b); +int gsl_matrix_int_scale (gsl_matrix_int * a, const int x); +int gsl_matrix_int_scale_rows (gsl_matrix_int * a, const gsl_vector_int * x); +int gsl_matrix_int_scale_columns (gsl_matrix_int * a, const gsl_vector_int * x); +int gsl_matrix_int_add_constant (gsl_matrix_int * a, const int x); +int gsl_matrix_int_add_diagonal (gsl_matrix_int * a, const int x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_int_get_row(gsl_vector_int * v, const gsl_matrix_int * m, const size_t i); +int gsl_matrix_int_get_col(gsl_vector_int * v, const gsl_matrix_int * m, const size_t j); +int gsl_matrix_int_set_row(gsl_matrix_int * m, const size_t i, const gsl_vector_int * v); +int gsl_matrix_int_set_col(gsl_matrix_int * m, const size_t j, const gsl_vector_int * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL int gsl_matrix_int_get(const gsl_matrix_int * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_int_set(gsl_matrix_int * m, const size_t i, const size_t j, const int x); +INLINE_DECL int * gsl_matrix_int_ptr(gsl_matrix_int * m, const size_t i, const size_t j); +INLINE_DECL const int * gsl_matrix_int_const_ptr(const gsl_matrix_int * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +int +gsl_matrix_int_get(const gsl_matrix_int * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_int_set(gsl_matrix_int * m, const size_t i, const size_t j, const int x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +int * +gsl_matrix_int_ptr(gsl_matrix_int * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (int *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const int * +gsl_matrix_int_const_ptr(const gsl_matrix_int * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const int *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long.h new file mode 100644 index 0000000..7ba99dc --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_LONG_H__ +#define __GSL_MATRIX_LONG_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + long * data; + gsl_block_long * block; + int owner; +} gsl_matrix_long; + +typedef struct +{ + gsl_matrix_long matrix; +} _gsl_matrix_long_view; + +typedef _gsl_matrix_long_view gsl_matrix_long_view; + +typedef struct +{ + gsl_matrix_long matrix; +} _gsl_matrix_long_const_view; + +typedef const _gsl_matrix_long_const_view gsl_matrix_long_const_view; + +/* Allocation */ + +gsl_matrix_long * +gsl_matrix_long_alloc (const size_t n1, const size_t n2); + +gsl_matrix_long * +gsl_matrix_long_calloc (const size_t n1, const size_t n2); + +gsl_matrix_long * +gsl_matrix_long_alloc_from_block (gsl_block_long * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_long * +gsl_matrix_long_alloc_from_matrix (gsl_matrix_long * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_long * +gsl_vector_long_alloc_row_from_matrix (gsl_matrix_long * m, + const size_t i); + +gsl_vector_long * +gsl_vector_long_alloc_col_from_matrix (gsl_matrix_long * m, + const size_t j); + +void gsl_matrix_long_free (gsl_matrix_long * m); + +/* Views */ + +_gsl_matrix_long_view +gsl_matrix_long_submatrix (gsl_matrix_long * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_long_view +gsl_matrix_long_row (gsl_matrix_long * m, const size_t i); + +_gsl_vector_long_view +gsl_matrix_long_column (gsl_matrix_long * m, const size_t j); + +_gsl_vector_long_view +gsl_matrix_long_diagonal (gsl_matrix_long * m); + +_gsl_vector_long_view +gsl_matrix_long_subdiagonal (gsl_matrix_long * m, const size_t k); + +_gsl_vector_long_view +gsl_matrix_long_superdiagonal (gsl_matrix_long * m, const size_t k); + +_gsl_vector_long_view +gsl_matrix_long_subrow (gsl_matrix_long * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_long_view +gsl_matrix_long_subcolumn (gsl_matrix_long * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_long_view +gsl_matrix_long_view_array (long * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_view +gsl_matrix_long_view_array_with_tda (long * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_long_view +gsl_matrix_long_view_vector (gsl_vector_long * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_view +gsl_matrix_long_view_vector_with_tda (gsl_vector_long * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_long_const_view +gsl_matrix_long_const_submatrix (const gsl_matrix_long * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_long_const_view +gsl_matrix_long_const_row (const gsl_matrix_long * m, + const size_t i); + +_gsl_vector_long_const_view +gsl_matrix_long_const_column (const gsl_matrix_long * m, + const size_t j); + +_gsl_vector_long_const_view +gsl_matrix_long_const_diagonal (const gsl_matrix_long * m); + +_gsl_vector_long_const_view +gsl_matrix_long_const_subdiagonal (const gsl_matrix_long * m, + const size_t k); + +_gsl_vector_long_const_view +gsl_matrix_long_const_superdiagonal (const gsl_matrix_long * m, + const size_t k); + +_gsl_vector_long_const_view +gsl_matrix_long_const_subrow (const gsl_matrix_long * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_long_const_view +gsl_matrix_long_const_subcolumn (const gsl_matrix_long * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_long_const_view +gsl_matrix_long_const_view_array (const long * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_const_view +gsl_matrix_long_const_view_array_with_tda (const long * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_long_const_view +gsl_matrix_long_const_view_vector (const gsl_vector_long * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_const_view +gsl_matrix_long_const_view_vector_with_tda (const gsl_vector_long * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_long_set_zero (gsl_matrix_long * m); +void gsl_matrix_long_set_identity (gsl_matrix_long * m); +void gsl_matrix_long_set_all (gsl_matrix_long * m, long x); + +int gsl_matrix_long_fread (FILE * stream, gsl_matrix_long * m) ; +int gsl_matrix_long_fwrite (FILE * stream, const gsl_matrix_long * m) ; +int gsl_matrix_long_fscanf (FILE * stream, gsl_matrix_long * m); +int gsl_matrix_long_fprintf (FILE * stream, const gsl_matrix_long * m, const char * format); + +int gsl_matrix_long_memcpy(gsl_matrix_long * dest, const gsl_matrix_long * src); +int gsl_matrix_long_swap(gsl_matrix_long * m1, gsl_matrix_long * m2); +int gsl_matrix_long_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_long * dest, const gsl_matrix_long * src); + +int gsl_matrix_long_swap_rows(gsl_matrix_long * m, const size_t i, const size_t j); +int gsl_matrix_long_swap_columns(gsl_matrix_long * m, const size_t i, const size_t j); +int gsl_matrix_long_swap_rowcol(gsl_matrix_long * m, const size_t i, const size_t j); +int gsl_matrix_long_transpose (gsl_matrix_long * m); +int gsl_matrix_long_transpose_memcpy (gsl_matrix_long * dest, const gsl_matrix_long * src); +int gsl_matrix_long_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_long * dest, const gsl_matrix_long * src); + +long gsl_matrix_long_max (const gsl_matrix_long * m); +long gsl_matrix_long_min (const gsl_matrix_long * m); +void gsl_matrix_long_minmax (const gsl_matrix_long * m, long * min_out, long * max_out); + +void gsl_matrix_long_max_index (const gsl_matrix_long * m, size_t * imax, size_t *jmax); +void gsl_matrix_long_min_index (const gsl_matrix_long * m, size_t * imin, size_t *jmin); +void gsl_matrix_long_minmax_index (const gsl_matrix_long * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_long_equal (const gsl_matrix_long * a, const gsl_matrix_long * b); + +int gsl_matrix_long_isnull (const gsl_matrix_long * m); +int gsl_matrix_long_ispos (const gsl_matrix_long * m); +int gsl_matrix_long_isneg (const gsl_matrix_long * m); +int gsl_matrix_long_isnonneg (const gsl_matrix_long * m); + +long gsl_matrix_long_norm1 (const gsl_matrix_long * m); + +int gsl_matrix_long_add (gsl_matrix_long * a, const gsl_matrix_long * b); +int gsl_matrix_long_sub (gsl_matrix_long * a, const gsl_matrix_long * b); +int gsl_matrix_long_mul_elements (gsl_matrix_long * a, const gsl_matrix_long * b); +int gsl_matrix_long_div_elements (gsl_matrix_long * a, const gsl_matrix_long * b); +int gsl_matrix_long_scale (gsl_matrix_long * a, const long x); +int gsl_matrix_long_scale_rows (gsl_matrix_long * a, const gsl_vector_long * x); +int gsl_matrix_long_scale_columns (gsl_matrix_long * a, const gsl_vector_long * x); +int gsl_matrix_long_add_constant (gsl_matrix_long * a, const long x); +int gsl_matrix_long_add_diagonal (gsl_matrix_long * a, const long x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_long_get_row(gsl_vector_long * v, const gsl_matrix_long * m, const size_t i); +int gsl_matrix_long_get_col(gsl_vector_long * v, const gsl_matrix_long * m, const size_t j); +int gsl_matrix_long_set_row(gsl_matrix_long * m, const size_t i, const gsl_vector_long * v); +int gsl_matrix_long_set_col(gsl_matrix_long * m, const size_t j, const gsl_vector_long * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL long gsl_matrix_long_get(const gsl_matrix_long * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_long_set(gsl_matrix_long * m, const size_t i, const size_t j, const long x); +INLINE_DECL long * gsl_matrix_long_ptr(gsl_matrix_long * m, const size_t i, const size_t j); +INLINE_DECL const long * gsl_matrix_long_const_ptr(const gsl_matrix_long * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +long +gsl_matrix_long_get(const gsl_matrix_long * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_long_set(gsl_matrix_long * m, const size_t i, const size_t j, const long x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +long * +gsl_matrix_long_ptr(gsl_matrix_long * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (long *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const long * +gsl_matrix_long_const_ptr(const gsl_matrix_long * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const long *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long_double.h new file mode 100644 index 0000000..5d3e429 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_long_double.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_LONG_DOUBLE_H__ +#define __GSL_MATRIX_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + long double * data; + gsl_block_long_double * block; + int owner; +} gsl_matrix_long_double; + +typedef struct +{ + gsl_matrix_long_double matrix; +} _gsl_matrix_long_double_view; + +typedef _gsl_matrix_long_double_view gsl_matrix_long_double_view; + +typedef struct +{ + gsl_matrix_long_double matrix; +} _gsl_matrix_long_double_const_view; + +typedef const _gsl_matrix_long_double_const_view gsl_matrix_long_double_const_view; + +/* Allocation */ + +gsl_matrix_long_double * +gsl_matrix_long_double_alloc (const size_t n1, const size_t n2); + +gsl_matrix_long_double * +gsl_matrix_long_double_calloc (const size_t n1, const size_t n2); + +gsl_matrix_long_double * +gsl_matrix_long_double_alloc_from_block (gsl_block_long_double * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_long_double * +gsl_matrix_long_double_alloc_from_matrix (gsl_matrix_long_double * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_long_double * +gsl_vector_long_double_alloc_row_from_matrix (gsl_matrix_long_double * m, + const size_t i); + +gsl_vector_long_double * +gsl_vector_long_double_alloc_col_from_matrix (gsl_matrix_long_double * m, + const size_t j); + +void gsl_matrix_long_double_free (gsl_matrix_long_double * m); + +/* Views */ + +_gsl_matrix_long_double_view +gsl_matrix_long_double_submatrix (gsl_matrix_long_double * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_long_double_view +gsl_matrix_long_double_row (gsl_matrix_long_double * m, const size_t i); + +_gsl_vector_long_double_view +gsl_matrix_long_double_column (gsl_matrix_long_double * m, const size_t j); + +_gsl_vector_long_double_view +gsl_matrix_long_double_diagonal (gsl_matrix_long_double * m); + +_gsl_vector_long_double_view +gsl_matrix_long_double_subdiagonal (gsl_matrix_long_double * m, const size_t k); + +_gsl_vector_long_double_view +gsl_matrix_long_double_superdiagonal (gsl_matrix_long_double * m, const size_t k); + +_gsl_vector_long_double_view +gsl_matrix_long_double_subrow (gsl_matrix_long_double * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_long_double_view +gsl_matrix_long_double_subcolumn (gsl_matrix_long_double * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_long_double_view +gsl_matrix_long_double_view_array (long double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_double_view +gsl_matrix_long_double_view_array_with_tda (long double * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_long_double_view +gsl_matrix_long_double_view_vector (gsl_vector_long_double * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_double_view +gsl_matrix_long_double_view_vector_with_tda (gsl_vector_long_double * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_long_double_const_view +gsl_matrix_long_double_const_submatrix (const gsl_matrix_long_double * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_row (const gsl_matrix_long_double * m, + const size_t i); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_column (const gsl_matrix_long_double * m, + const size_t j); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_diagonal (const gsl_matrix_long_double * m); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_subdiagonal (const gsl_matrix_long_double * m, + const size_t k); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_superdiagonal (const gsl_matrix_long_double * m, + const size_t k); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_subrow (const gsl_matrix_long_double * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_long_double_const_view +gsl_matrix_long_double_const_subcolumn (const gsl_matrix_long_double * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_long_double_const_view +gsl_matrix_long_double_const_view_array (const long double * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_double_const_view +gsl_matrix_long_double_const_view_array_with_tda (const long double * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_long_double_const_view +gsl_matrix_long_double_const_view_vector (const gsl_vector_long_double * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_long_double_const_view +gsl_matrix_long_double_const_view_vector_with_tda (const gsl_vector_long_double * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_long_double_set_zero (gsl_matrix_long_double * m); +void gsl_matrix_long_double_set_identity (gsl_matrix_long_double * m); +void gsl_matrix_long_double_set_all (gsl_matrix_long_double * m, long double x); + +int gsl_matrix_long_double_fread (FILE * stream, gsl_matrix_long_double * m) ; +int gsl_matrix_long_double_fwrite (FILE * stream, const gsl_matrix_long_double * m) ; +int gsl_matrix_long_double_fscanf (FILE * stream, gsl_matrix_long_double * m); +int gsl_matrix_long_double_fprintf (FILE * stream, const gsl_matrix_long_double * m, const char * format); + +int gsl_matrix_long_double_memcpy(gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); +int gsl_matrix_long_double_swap(gsl_matrix_long_double * m1, gsl_matrix_long_double * m2); +int gsl_matrix_long_double_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); + +int gsl_matrix_long_double_swap_rows(gsl_matrix_long_double * m, const size_t i, const size_t j); +int gsl_matrix_long_double_swap_columns(gsl_matrix_long_double * m, const size_t i, const size_t j); +int gsl_matrix_long_double_swap_rowcol(gsl_matrix_long_double * m, const size_t i, const size_t j); +int gsl_matrix_long_double_transpose (gsl_matrix_long_double * m); +int gsl_matrix_long_double_transpose_memcpy (gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); +int gsl_matrix_long_double_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_long_double * dest, const gsl_matrix_long_double * src); + +long double gsl_matrix_long_double_max (const gsl_matrix_long_double * m); +long double gsl_matrix_long_double_min (const gsl_matrix_long_double * m); +void gsl_matrix_long_double_minmax (const gsl_matrix_long_double * m, long double * min_out, long double * max_out); + +void gsl_matrix_long_double_max_index (const gsl_matrix_long_double * m, size_t * imax, size_t *jmax); +void gsl_matrix_long_double_min_index (const gsl_matrix_long_double * m, size_t * imin, size_t *jmin); +void gsl_matrix_long_double_minmax_index (const gsl_matrix_long_double * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_long_double_equal (const gsl_matrix_long_double * a, const gsl_matrix_long_double * b); + +int gsl_matrix_long_double_isnull (const gsl_matrix_long_double * m); +int gsl_matrix_long_double_ispos (const gsl_matrix_long_double * m); +int gsl_matrix_long_double_isneg (const gsl_matrix_long_double * m); +int gsl_matrix_long_double_isnonneg (const gsl_matrix_long_double * m); + +long double gsl_matrix_long_double_norm1 (const gsl_matrix_long_double * m); + +int gsl_matrix_long_double_add (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); +int gsl_matrix_long_double_sub (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); +int gsl_matrix_long_double_mul_elements (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); +int gsl_matrix_long_double_div_elements (gsl_matrix_long_double * a, const gsl_matrix_long_double * b); +int gsl_matrix_long_double_scale (gsl_matrix_long_double * a, const long double x); +int gsl_matrix_long_double_scale_rows (gsl_matrix_long_double * a, const gsl_vector_long_double * x); +int gsl_matrix_long_double_scale_columns (gsl_matrix_long_double * a, const gsl_vector_long_double * x); +int gsl_matrix_long_double_add_constant (gsl_matrix_long_double * a, const long double x); +int gsl_matrix_long_double_add_diagonal (gsl_matrix_long_double * a, const long double x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_long_double_get_row(gsl_vector_long_double * v, const gsl_matrix_long_double * m, const size_t i); +int gsl_matrix_long_double_get_col(gsl_vector_long_double * v, const gsl_matrix_long_double * m, const size_t j); +int gsl_matrix_long_double_set_row(gsl_matrix_long_double * m, const size_t i, const gsl_vector_long_double * v); +int gsl_matrix_long_double_set_col(gsl_matrix_long_double * m, const size_t j, const gsl_vector_long_double * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL long double gsl_matrix_long_double_get(const gsl_matrix_long_double * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_long_double_set(gsl_matrix_long_double * m, const size_t i, const size_t j, const long double x); +INLINE_DECL long double * gsl_matrix_long_double_ptr(gsl_matrix_long_double * m, const size_t i, const size_t j); +INLINE_DECL const long double * gsl_matrix_long_double_const_ptr(const gsl_matrix_long_double * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +long double +gsl_matrix_long_double_get(const gsl_matrix_long_double * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_long_double_set(gsl_matrix_long_double * m, const size_t i, const size_t j, const long double x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +long double * +gsl_matrix_long_double_ptr(gsl_matrix_long_double * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (long double *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const long double * +gsl_matrix_long_double_const_ptr(const gsl_matrix_long_double * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const long double *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_short.h new file mode 100644 index 0000000..6058207 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_short.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_SHORT_H__ +#define __GSL_MATRIX_SHORT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + short * data; + gsl_block_short * block; + int owner; +} gsl_matrix_short; + +typedef struct +{ + gsl_matrix_short matrix; +} _gsl_matrix_short_view; + +typedef _gsl_matrix_short_view gsl_matrix_short_view; + +typedef struct +{ + gsl_matrix_short matrix; +} _gsl_matrix_short_const_view; + +typedef const _gsl_matrix_short_const_view gsl_matrix_short_const_view; + +/* Allocation */ + +gsl_matrix_short * +gsl_matrix_short_alloc (const size_t n1, const size_t n2); + +gsl_matrix_short * +gsl_matrix_short_calloc (const size_t n1, const size_t n2); + +gsl_matrix_short * +gsl_matrix_short_alloc_from_block (gsl_block_short * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_short * +gsl_matrix_short_alloc_from_matrix (gsl_matrix_short * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_short * +gsl_vector_short_alloc_row_from_matrix (gsl_matrix_short * m, + const size_t i); + +gsl_vector_short * +gsl_vector_short_alloc_col_from_matrix (gsl_matrix_short * m, + const size_t j); + +void gsl_matrix_short_free (gsl_matrix_short * m); + +/* Views */ + +_gsl_matrix_short_view +gsl_matrix_short_submatrix (gsl_matrix_short * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_short_view +gsl_matrix_short_row (gsl_matrix_short * m, const size_t i); + +_gsl_vector_short_view +gsl_matrix_short_column (gsl_matrix_short * m, const size_t j); + +_gsl_vector_short_view +gsl_matrix_short_diagonal (gsl_matrix_short * m); + +_gsl_vector_short_view +gsl_matrix_short_subdiagonal (gsl_matrix_short * m, const size_t k); + +_gsl_vector_short_view +gsl_matrix_short_superdiagonal (gsl_matrix_short * m, const size_t k); + +_gsl_vector_short_view +gsl_matrix_short_subrow (gsl_matrix_short * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_short_view +gsl_matrix_short_subcolumn (gsl_matrix_short * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_short_view +gsl_matrix_short_view_array (short * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_short_view +gsl_matrix_short_view_array_with_tda (short * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_short_view +gsl_matrix_short_view_vector (gsl_vector_short * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_short_view +gsl_matrix_short_view_vector_with_tda (gsl_vector_short * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_short_const_view +gsl_matrix_short_const_submatrix (const gsl_matrix_short * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_short_const_view +gsl_matrix_short_const_row (const gsl_matrix_short * m, + const size_t i); + +_gsl_vector_short_const_view +gsl_matrix_short_const_column (const gsl_matrix_short * m, + const size_t j); + +_gsl_vector_short_const_view +gsl_matrix_short_const_diagonal (const gsl_matrix_short * m); + +_gsl_vector_short_const_view +gsl_matrix_short_const_subdiagonal (const gsl_matrix_short * m, + const size_t k); + +_gsl_vector_short_const_view +gsl_matrix_short_const_superdiagonal (const gsl_matrix_short * m, + const size_t k); + +_gsl_vector_short_const_view +gsl_matrix_short_const_subrow (const gsl_matrix_short * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_short_const_view +gsl_matrix_short_const_subcolumn (const gsl_matrix_short * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_short_const_view +gsl_matrix_short_const_view_array (const short * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_short_const_view +gsl_matrix_short_const_view_array_with_tda (const short * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_short_const_view +gsl_matrix_short_const_view_vector (const gsl_vector_short * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_short_const_view +gsl_matrix_short_const_view_vector_with_tda (const gsl_vector_short * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_short_set_zero (gsl_matrix_short * m); +void gsl_matrix_short_set_identity (gsl_matrix_short * m); +void gsl_matrix_short_set_all (gsl_matrix_short * m, short x); + +int gsl_matrix_short_fread (FILE * stream, gsl_matrix_short * m) ; +int gsl_matrix_short_fwrite (FILE * stream, const gsl_matrix_short * m) ; +int gsl_matrix_short_fscanf (FILE * stream, gsl_matrix_short * m); +int gsl_matrix_short_fprintf (FILE * stream, const gsl_matrix_short * m, const char * format); + +int gsl_matrix_short_memcpy(gsl_matrix_short * dest, const gsl_matrix_short * src); +int gsl_matrix_short_swap(gsl_matrix_short * m1, gsl_matrix_short * m2); +int gsl_matrix_short_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_short * dest, const gsl_matrix_short * src); + +int gsl_matrix_short_swap_rows(gsl_matrix_short * m, const size_t i, const size_t j); +int gsl_matrix_short_swap_columns(gsl_matrix_short * m, const size_t i, const size_t j); +int gsl_matrix_short_swap_rowcol(gsl_matrix_short * m, const size_t i, const size_t j); +int gsl_matrix_short_transpose (gsl_matrix_short * m); +int gsl_matrix_short_transpose_memcpy (gsl_matrix_short * dest, const gsl_matrix_short * src); +int gsl_matrix_short_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_short * dest, const gsl_matrix_short * src); + +short gsl_matrix_short_max (const gsl_matrix_short * m); +short gsl_matrix_short_min (const gsl_matrix_short * m); +void gsl_matrix_short_minmax (const gsl_matrix_short * m, short * min_out, short * max_out); + +void gsl_matrix_short_max_index (const gsl_matrix_short * m, size_t * imax, size_t *jmax); +void gsl_matrix_short_min_index (const gsl_matrix_short * m, size_t * imin, size_t *jmin); +void gsl_matrix_short_minmax_index (const gsl_matrix_short * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_short_equal (const gsl_matrix_short * a, const gsl_matrix_short * b); + +int gsl_matrix_short_isnull (const gsl_matrix_short * m); +int gsl_matrix_short_ispos (const gsl_matrix_short * m); +int gsl_matrix_short_isneg (const gsl_matrix_short * m); +int gsl_matrix_short_isnonneg (const gsl_matrix_short * m); + +short gsl_matrix_short_norm1 (const gsl_matrix_short * m); + +int gsl_matrix_short_add (gsl_matrix_short * a, const gsl_matrix_short * b); +int gsl_matrix_short_sub (gsl_matrix_short * a, const gsl_matrix_short * b); +int gsl_matrix_short_mul_elements (gsl_matrix_short * a, const gsl_matrix_short * b); +int gsl_matrix_short_div_elements (gsl_matrix_short * a, const gsl_matrix_short * b); +int gsl_matrix_short_scale (gsl_matrix_short * a, const short x); +int gsl_matrix_short_scale_rows (gsl_matrix_short * a, const gsl_vector_short * x); +int gsl_matrix_short_scale_columns (gsl_matrix_short * a, const gsl_vector_short * x); +int gsl_matrix_short_add_constant (gsl_matrix_short * a, const short x); +int gsl_matrix_short_add_diagonal (gsl_matrix_short * a, const short x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_short_get_row(gsl_vector_short * v, const gsl_matrix_short * m, const size_t i); +int gsl_matrix_short_get_col(gsl_vector_short * v, const gsl_matrix_short * m, const size_t j); +int gsl_matrix_short_set_row(gsl_matrix_short * m, const size_t i, const gsl_vector_short * v); +int gsl_matrix_short_set_col(gsl_matrix_short * m, const size_t j, const gsl_vector_short * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL short gsl_matrix_short_get(const gsl_matrix_short * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_short_set(gsl_matrix_short * m, const size_t i, const size_t j, const short x); +INLINE_DECL short * gsl_matrix_short_ptr(gsl_matrix_short * m, const size_t i, const size_t j); +INLINE_DECL const short * gsl_matrix_short_const_ptr(const gsl_matrix_short * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +short +gsl_matrix_short_get(const gsl_matrix_short * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_short_set(gsl_matrix_short * m, const size_t i, const size_t j, const short x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +short * +gsl_matrix_short_ptr(gsl_matrix_short * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (short *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const short * +gsl_matrix_short_const_ptr(const gsl_matrix_short * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const short *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uchar.h new file mode 100644 index 0000000..9447e82 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uchar.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_UCHAR_H__ +#define __GSL_MATRIX_UCHAR_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + unsigned char * data; + gsl_block_uchar * block; + int owner; +} gsl_matrix_uchar; + +typedef struct +{ + gsl_matrix_uchar matrix; +} _gsl_matrix_uchar_view; + +typedef _gsl_matrix_uchar_view gsl_matrix_uchar_view; + +typedef struct +{ + gsl_matrix_uchar matrix; +} _gsl_matrix_uchar_const_view; + +typedef const _gsl_matrix_uchar_const_view gsl_matrix_uchar_const_view; + +/* Allocation */ + +gsl_matrix_uchar * +gsl_matrix_uchar_alloc (const size_t n1, const size_t n2); + +gsl_matrix_uchar * +gsl_matrix_uchar_calloc (const size_t n1, const size_t n2); + +gsl_matrix_uchar * +gsl_matrix_uchar_alloc_from_block (gsl_block_uchar * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_uchar * +gsl_matrix_uchar_alloc_from_matrix (gsl_matrix_uchar * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_uchar * +gsl_vector_uchar_alloc_row_from_matrix (gsl_matrix_uchar * m, + const size_t i); + +gsl_vector_uchar * +gsl_vector_uchar_alloc_col_from_matrix (gsl_matrix_uchar * m, + const size_t j); + +void gsl_matrix_uchar_free (gsl_matrix_uchar * m); + +/* Views */ + +_gsl_matrix_uchar_view +gsl_matrix_uchar_submatrix (gsl_matrix_uchar * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_uchar_view +gsl_matrix_uchar_row (gsl_matrix_uchar * m, const size_t i); + +_gsl_vector_uchar_view +gsl_matrix_uchar_column (gsl_matrix_uchar * m, const size_t j); + +_gsl_vector_uchar_view +gsl_matrix_uchar_diagonal (gsl_matrix_uchar * m); + +_gsl_vector_uchar_view +gsl_matrix_uchar_subdiagonal (gsl_matrix_uchar * m, const size_t k); + +_gsl_vector_uchar_view +gsl_matrix_uchar_superdiagonal (gsl_matrix_uchar * m, const size_t k); + +_gsl_vector_uchar_view +gsl_matrix_uchar_subrow (gsl_matrix_uchar * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_uchar_view +gsl_matrix_uchar_subcolumn (gsl_matrix_uchar * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_uchar_view +gsl_matrix_uchar_view_array (unsigned char * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_uchar_view +gsl_matrix_uchar_view_array_with_tda (unsigned char * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_uchar_view +gsl_matrix_uchar_view_vector (gsl_vector_uchar * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_uchar_view +gsl_matrix_uchar_view_vector_with_tda (gsl_vector_uchar * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_uchar_const_view +gsl_matrix_uchar_const_submatrix (const gsl_matrix_uchar * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_row (const gsl_matrix_uchar * m, + const size_t i); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_column (const gsl_matrix_uchar * m, + const size_t j); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_diagonal (const gsl_matrix_uchar * m); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_subdiagonal (const gsl_matrix_uchar * m, + const size_t k); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_superdiagonal (const gsl_matrix_uchar * m, + const size_t k); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_subrow (const gsl_matrix_uchar * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_uchar_const_view +gsl_matrix_uchar_const_subcolumn (const gsl_matrix_uchar * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_uchar_const_view +gsl_matrix_uchar_const_view_array (const unsigned char * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_uchar_const_view +gsl_matrix_uchar_const_view_array_with_tda (const unsigned char * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_uchar_const_view +gsl_matrix_uchar_const_view_vector (const gsl_vector_uchar * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_uchar_const_view +gsl_matrix_uchar_const_view_vector_with_tda (const gsl_vector_uchar * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_uchar_set_zero (gsl_matrix_uchar * m); +void gsl_matrix_uchar_set_identity (gsl_matrix_uchar * m); +void gsl_matrix_uchar_set_all (gsl_matrix_uchar * m, unsigned char x); + +int gsl_matrix_uchar_fread (FILE * stream, gsl_matrix_uchar * m) ; +int gsl_matrix_uchar_fwrite (FILE * stream, const gsl_matrix_uchar * m) ; +int gsl_matrix_uchar_fscanf (FILE * stream, gsl_matrix_uchar * m); +int gsl_matrix_uchar_fprintf (FILE * stream, const gsl_matrix_uchar * m, const char * format); + +int gsl_matrix_uchar_memcpy(gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); +int gsl_matrix_uchar_swap(gsl_matrix_uchar * m1, gsl_matrix_uchar * m2); +int gsl_matrix_uchar_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); + +int gsl_matrix_uchar_swap_rows(gsl_matrix_uchar * m, const size_t i, const size_t j); +int gsl_matrix_uchar_swap_columns(gsl_matrix_uchar * m, const size_t i, const size_t j); +int gsl_matrix_uchar_swap_rowcol(gsl_matrix_uchar * m, const size_t i, const size_t j); +int gsl_matrix_uchar_transpose (gsl_matrix_uchar * m); +int gsl_matrix_uchar_transpose_memcpy (gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); +int gsl_matrix_uchar_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_uchar * dest, const gsl_matrix_uchar * src); + +unsigned char gsl_matrix_uchar_max (const gsl_matrix_uchar * m); +unsigned char gsl_matrix_uchar_min (const gsl_matrix_uchar * m); +void gsl_matrix_uchar_minmax (const gsl_matrix_uchar * m, unsigned char * min_out, unsigned char * max_out); + +void gsl_matrix_uchar_max_index (const gsl_matrix_uchar * m, size_t * imax, size_t *jmax); +void gsl_matrix_uchar_min_index (const gsl_matrix_uchar * m, size_t * imin, size_t *jmin); +void gsl_matrix_uchar_minmax_index (const gsl_matrix_uchar * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_uchar_equal (const gsl_matrix_uchar * a, const gsl_matrix_uchar * b); + +int gsl_matrix_uchar_isnull (const gsl_matrix_uchar * m); +int gsl_matrix_uchar_ispos (const gsl_matrix_uchar * m); +int gsl_matrix_uchar_isneg (const gsl_matrix_uchar * m); +int gsl_matrix_uchar_isnonneg (const gsl_matrix_uchar * m); + +unsigned char gsl_matrix_uchar_norm1 (const gsl_matrix_uchar * m); + +int gsl_matrix_uchar_add (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); +int gsl_matrix_uchar_sub (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); +int gsl_matrix_uchar_mul_elements (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); +int gsl_matrix_uchar_div_elements (gsl_matrix_uchar * a, const gsl_matrix_uchar * b); +int gsl_matrix_uchar_scale (gsl_matrix_uchar * a, const unsigned char x); +int gsl_matrix_uchar_scale_rows (gsl_matrix_uchar * a, const gsl_vector_uchar * x); +int gsl_matrix_uchar_scale_columns (gsl_matrix_uchar * a, const gsl_vector_uchar * x); +int gsl_matrix_uchar_add_constant (gsl_matrix_uchar * a, const unsigned char x); +int gsl_matrix_uchar_add_diagonal (gsl_matrix_uchar * a, const unsigned char x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_uchar_get_row(gsl_vector_uchar * v, const gsl_matrix_uchar * m, const size_t i); +int gsl_matrix_uchar_get_col(gsl_vector_uchar * v, const gsl_matrix_uchar * m, const size_t j); +int gsl_matrix_uchar_set_row(gsl_matrix_uchar * m, const size_t i, const gsl_vector_uchar * v); +int gsl_matrix_uchar_set_col(gsl_matrix_uchar * m, const size_t j, const gsl_vector_uchar * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL unsigned char gsl_matrix_uchar_get(const gsl_matrix_uchar * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_uchar_set(gsl_matrix_uchar * m, const size_t i, const size_t j, const unsigned char x); +INLINE_DECL unsigned char * gsl_matrix_uchar_ptr(gsl_matrix_uchar * m, const size_t i, const size_t j); +INLINE_DECL const unsigned char * gsl_matrix_uchar_const_ptr(const gsl_matrix_uchar * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +unsigned char +gsl_matrix_uchar_get(const gsl_matrix_uchar * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_uchar_set(gsl_matrix_uchar * m, const size_t i, const size_t j, const unsigned char x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +unsigned char * +gsl_matrix_uchar_ptr(gsl_matrix_uchar * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (unsigned char *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const unsigned char * +gsl_matrix_uchar_const_ptr(const gsl_matrix_uchar * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const unsigned char *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uint.h new file mode 100644 index 0000000..510f39c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_uint.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_UINT_H__ +#define __GSL_MATRIX_UINT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + unsigned int * data; + gsl_block_uint * block; + int owner; +} gsl_matrix_uint; + +typedef struct +{ + gsl_matrix_uint matrix; +} _gsl_matrix_uint_view; + +typedef _gsl_matrix_uint_view gsl_matrix_uint_view; + +typedef struct +{ + gsl_matrix_uint matrix; +} _gsl_matrix_uint_const_view; + +typedef const _gsl_matrix_uint_const_view gsl_matrix_uint_const_view; + +/* Allocation */ + +gsl_matrix_uint * +gsl_matrix_uint_alloc (const size_t n1, const size_t n2); + +gsl_matrix_uint * +gsl_matrix_uint_calloc (const size_t n1, const size_t n2); + +gsl_matrix_uint * +gsl_matrix_uint_alloc_from_block (gsl_block_uint * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_uint * +gsl_matrix_uint_alloc_from_matrix (gsl_matrix_uint * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_uint * +gsl_vector_uint_alloc_row_from_matrix (gsl_matrix_uint * m, + const size_t i); + +gsl_vector_uint * +gsl_vector_uint_alloc_col_from_matrix (gsl_matrix_uint * m, + const size_t j); + +void gsl_matrix_uint_free (gsl_matrix_uint * m); + +/* Views */ + +_gsl_matrix_uint_view +gsl_matrix_uint_submatrix (gsl_matrix_uint * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_uint_view +gsl_matrix_uint_row (gsl_matrix_uint * m, const size_t i); + +_gsl_vector_uint_view +gsl_matrix_uint_column (gsl_matrix_uint * m, const size_t j); + +_gsl_vector_uint_view +gsl_matrix_uint_diagonal (gsl_matrix_uint * m); + +_gsl_vector_uint_view +gsl_matrix_uint_subdiagonal (gsl_matrix_uint * m, const size_t k); + +_gsl_vector_uint_view +gsl_matrix_uint_superdiagonal (gsl_matrix_uint * m, const size_t k); + +_gsl_vector_uint_view +gsl_matrix_uint_subrow (gsl_matrix_uint * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_uint_view +gsl_matrix_uint_subcolumn (gsl_matrix_uint * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_uint_view +gsl_matrix_uint_view_array (unsigned int * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_uint_view +gsl_matrix_uint_view_array_with_tda (unsigned int * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_uint_view +gsl_matrix_uint_view_vector (gsl_vector_uint * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_uint_view +gsl_matrix_uint_view_vector_with_tda (gsl_vector_uint * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_uint_const_view +gsl_matrix_uint_const_submatrix (const gsl_matrix_uint * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_row (const gsl_matrix_uint * m, + const size_t i); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_column (const gsl_matrix_uint * m, + const size_t j); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_diagonal (const gsl_matrix_uint * m); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_subdiagonal (const gsl_matrix_uint * m, + const size_t k); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_superdiagonal (const gsl_matrix_uint * m, + const size_t k); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_subrow (const gsl_matrix_uint * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_uint_const_view +gsl_matrix_uint_const_subcolumn (const gsl_matrix_uint * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_uint_const_view +gsl_matrix_uint_const_view_array (const unsigned int * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_uint_const_view +gsl_matrix_uint_const_view_array_with_tda (const unsigned int * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_uint_const_view +gsl_matrix_uint_const_view_vector (const gsl_vector_uint * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_uint_const_view +gsl_matrix_uint_const_view_vector_with_tda (const gsl_vector_uint * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_uint_set_zero (gsl_matrix_uint * m); +void gsl_matrix_uint_set_identity (gsl_matrix_uint * m); +void gsl_matrix_uint_set_all (gsl_matrix_uint * m, unsigned int x); + +int gsl_matrix_uint_fread (FILE * stream, gsl_matrix_uint * m) ; +int gsl_matrix_uint_fwrite (FILE * stream, const gsl_matrix_uint * m) ; +int gsl_matrix_uint_fscanf (FILE * stream, gsl_matrix_uint * m); +int gsl_matrix_uint_fprintf (FILE * stream, const gsl_matrix_uint * m, const char * format); + +int gsl_matrix_uint_memcpy(gsl_matrix_uint * dest, const gsl_matrix_uint * src); +int gsl_matrix_uint_swap(gsl_matrix_uint * m1, gsl_matrix_uint * m2); +int gsl_matrix_uint_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_uint * dest, const gsl_matrix_uint * src); + +int gsl_matrix_uint_swap_rows(gsl_matrix_uint * m, const size_t i, const size_t j); +int gsl_matrix_uint_swap_columns(gsl_matrix_uint * m, const size_t i, const size_t j); +int gsl_matrix_uint_swap_rowcol(gsl_matrix_uint * m, const size_t i, const size_t j); +int gsl_matrix_uint_transpose (gsl_matrix_uint * m); +int gsl_matrix_uint_transpose_memcpy (gsl_matrix_uint * dest, const gsl_matrix_uint * src); +int gsl_matrix_uint_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_uint * dest, const gsl_matrix_uint * src); + +unsigned int gsl_matrix_uint_max (const gsl_matrix_uint * m); +unsigned int gsl_matrix_uint_min (const gsl_matrix_uint * m); +void gsl_matrix_uint_minmax (const gsl_matrix_uint * m, unsigned int * min_out, unsigned int * max_out); + +void gsl_matrix_uint_max_index (const gsl_matrix_uint * m, size_t * imax, size_t *jmax); +void gsl_matrix_uint_min_index (const gsl_matrix_uint * m, size_t * imin, size_t *jmin); +void gsl_matrix_uint_minmax_index (const gsl_matrix_uint * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_uint_equal (const gsl_matrix_uint * a, const gsl_matrix_uint * b); + +int gsl_matrix_uint_isnull (const gsl_matrix_uint * m); +int gsl_matrix_uint_ispos (const gsl_matrix_uint * m); +int gsl_matrix_uint_isneg (const gsl_matrix_uint * m); +int gsl_matrix_uint_isnonneg (const gsl_matrix_uint * m); + +unsigned int gsl_matrix_uint_norm1 (const gsl_matrix_uint * m); + +int gsl_matrix_uint_add (gsl_matrix_uint * a, const gsl_matrix_uint * b); +int gsl_matrix_uint_sub (gsl_matrix_uint * a, const gsl_matrix_uint * b); +int gsl_matrix_uint_mul_elements (gsl_matrix_uint * a, const gsl_matrix_uint * b); +int gsl_matrix_uint_div_elements (gsl_matrix_uint * a, const gsl_matrix_uint * b); +int gsl_matrix_uint_scale (gsl_matrix_uint * a, const unsigned int x); +int gsl_matrix_uint_scale_rows (gsl_matrix_uint * a, const gsl_vector_uint * x); +int gsl_matrix_uint_scale_columns (gsl_matrix_uint * a, const gsl_vector_uint * x); +int gsl_matrix_uint_add_constant (gsl_matrix_uint * a, const unsigned int x); +int gsl_matrix_uint_add_diagonal (gsl_matrix_uint * a, const unsigned int x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_uint_get_row(gsl_vector_uint * v, const gsl_matrix_uint * m, const size_t i); +int gsl_matrix_uint_get_col(gsl_vector_uint * v, const gsl_matrix_uint * m, const size_t j); +int gsl_matrix_uint_set_row(gsl_matrix_uint * m, const size_t i, const gsl_vector_uint * v); +int gsl_matrix_uint_set_col(gsl_matrix_uint * m, const size_t j, const gsl_vector_uint * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL unsigned int gsl_matrix_uint_get(const gsl_matrix_uint * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_uint_set(gsl_matrix_uint * m, const size_t i, const size_t j, const unsigned int x); +INLINE_DECL unsigned int * gsl_matrix_uint_ptr(gsl_matrix_uint * m, const size_t i, const size_t j); +INLINE_DECL const unsigned int * gsl_matrix_uint_const_ptr(const gsl_matrix_uint * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +unsigned int +gsl_matrix_uint_get(const gsl_matrix_uint * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_uint_set(gsl_matrix_uint * m, const size_t i, const size_t j, const unsigned int x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +unsigned int * +gsl_matrix_uint_ptr(gsl_matrix_uint * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (unsigned int *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const unsigned int * +gsl_matrix_uint_const_ptr(const gsl_matrix_uint * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const unsigned int *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ulong.h new file mode 100644 index 0000000..5e4a7ef --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ulong.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_ULONG_H__ +#define __GSL_MATRIX_ULONG_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + unsigned long * data; + gsl_block_ulong * block; + int owner; +} gsl_matrix_ulong; + +typedef struct +{ + gsl_matrix_ulong matrix; +} _gsl_matrix_ulong_view; + +typedef _gsl_matrix_ulong_view gsl_matrix_ulong_view; + +typedef struct +{ + gsl_matrix_ulong matrix; +} _gsl_matrix_ulong_const_view; + +typedef const _gsl_matrix_ulong_const_view gsl_matrix_ulong_const_view; + +/* Allocation */ + +gsl_matrix_ulong * +gsl_matrix_ulong_alloc (const size_t n1, const size_t n2); + +gsl_matrix_ulong * +gsl_matrix_ulong_calloc (const size_t n1, const size_t n2); + +gsl_matrix_ulong * +gsl_matrix_ulong_alloc_from_block (gsl_block_ulong * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_ulong * +gsl_matrix_ulong_alloc_from_matrix (gsl_matrix_ulong * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_ulong * +gsl_vector_ulong_alloc_row_from_matrix (gsl_matrix_ulong * m, + const size_t i); + +gsl_vector_ulong * +gsl_vector_ulong_alloc_col_from_matrix (gsl_matrix_ulong * m, + const size_t j); + +void gsl_matrix_ulong_free (gsl_matrix_ulong * m); + +/* Views */ + +_gsl_matrix_ulong_view +gsl_matrix_ulong_submatrix (gsl_matrix_ulong * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_ulong_view +gsl_matrix_ulong_row (gsl_matrix_ulong * m, const size_t i); + +_gsl_vector_ulong_view +gsl_matrix_ulong_column (gsl_matrix_ulong * m, const size_t j); + +_gsl_vector_ulong_view +gsl_matrix_ulong_diagonal (gsl_matrix_ulong * m); + +_gsl_vector_ulong_view +gsl_matrix_ulong_subdiagonal (gsl_matrix_ulong * m, const size_t k); + +_gsl_vector_ulong_view +gsl_matrix_ulong_superdiagonal (gsl_matrix_ulong * m, const size_t k); + +_gsl_vector_ulong_view +gsl_matrix_ulong_subrow (gsl_matrix_ulong * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_ulong_view +gsl_matrix_ulong_subcolumn (gsl_matrix_ulong * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_ulong_view +gsl_matrix_ulong_view_array (unsigned long * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_ulong_view +gsl_matrix_ulong_view_array_with_tda (unsigned long * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_ulong_view +gsl_matrix_ulong_view_vector (gsl_vector_ulong * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_ulong_view +gsl_matrix_ulong_view_vector_with_tda (gsl_vector_ulong * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_ulong_const_view +gsl_matrix_ulong_const_submatrix (const gsl_matrix_ulong * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_row (const gsl_matrix_ulong * m, + const size_t i); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_column (const gsl_matrix_ulong * m, + const size_t j); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_diagonal (const gsl_matrix_ulong * m); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_subdiagonal (const gsl_matrix_ulong * m, + const size_t k); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_superdiagonal (const gsl_matrix_ulong * m, + const size_t k); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_subrow (const gsl_matrix_ulong * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_ulong_const_view +gsl_matrix_ulong_const_subcolumn (const gsl_matrix_ulong * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_ulong_const_view +gsl_matrix_ulong_const_view_array (const unsigned long * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_ulong_const_view +gsl_matrix_ulong_const_view_array_with_tda (const unsigned long * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_ulong_const_view +gsl_matrix_ulong_const_view_vector (const gsl_vector_ulong * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_ulong_const_view +gsl_matrix_ulong_const_view_vector_with_tda (const gsl_vector_ulong * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_ulong_set_zero (gsl_matrix_ulong * m); +void gsl_matrix_ulong_set_identity (gsl_matrix_ulong * m); +void gsl_matrix_ulong_set_all (gsl_matrix_ulong * m, unsigned long x); + +int gsl_matrix_ulong_fread (FILE * stream, gsl_matrix_ulong * m) ; +int gsl_matrix_ulong_fwrite (FILE * stream, const gsl_matrix_ulong * m) ; +int gsl_matrix_ulong_fscanf (FILE * stream, gsl_matrix_ulong * m); +int gsl_matrix_ulong_fprintf (FILE * stream, const gsl_matrix_ulong * m, const char * format); + +int gsl_matrix_ulong_memcpy(gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); +int gsl_matrix_ulong_swap(gsl_matrix_ulong * m1, gsl_matrix_ulong * m2); +int gsl_matrix_ulong_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); + +int gsl_matrix_ulong_swap_rows(gsl_matrix_ulong * m, const size_t i, const size_t j); +int gsl_matrix_ulong_swap_columns(gsl_matrix_ulong * m, const size_t i, const size_t j); +int gsl_matrix_ulong_swap_rowcol(gsl_matrix_ulong * m, const size_t i, const size_t j); +int gsl_matrix_ulong_transpose (gsl_matrix_ulong * m); +int gsl_matrix_ulong_transpose_memcpy (gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); +int gsl_matrix_ulong_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_ulong * dest, const gsl_matrix_ulong * src); + +unsigned long gsl_matrix_ulong_max (const gsl_matrix_ulong * m); +unsigned long gsl_matrix_ulong_min (const gsl_matrix_ulong * m); +void gsl_matrix_ulong_minmax (const gsl_matrix_ulong * m, unsigned long * min_out, unsigned long * max_out); + +void gsl_matrix_ulong_max_index (const gsl_matrix_ulong * m, size_t * imax, size_t *jmax); +void gsl_matrix_ulong_min_index (const gsl_matrix_ulong * m, size_t * imin, size_t *jmin); +void gsl_matrix_ulong_minmax_index (const gsl_matrix_ulong * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_ulong_equal (const gsl_matrix_ulong * a, const gsl_matrix_ulong * b); + +int gsl_matrix_ulong_isnull (const gsl_matrix_ulong * m); +int gsl_matrix_ulong_ispos (const gsl_matrix_ulong * m); +int gsl_matrix_ulong_isneg (const gsl_matrix_ulong * m); +int gsl_matrix_ulong_isnonneg (const gsl_matrix_ulong * m); + +unsigned long gsl_matrix_ulong_norm1 (const gsl_matrix_ulong * m); + +int gsl_matrix_ulong_add (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); +int gsl_matrix_ulong_sub (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); +int gsl_matrix_ulong_mul_elements (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); +int gsl_matrix_ulong_div_elements (gsl_matrix_ulong * a, const gsl_matrix_ulong * b); +int gsl_matrix_ulong_scale (gsl_matrix_ulong * a, const unsigned long x); +int gsl_matrix_ulong_scale_rows (gsl_matrix_ulong * a, const gsl_vector_ulong * x); +int gsl_matrix_ulong_scale_columns (gsl_matrix_ulong * a, const gsl_vector_ulong * x); +int gsl_matrix_ulong_add_constant (gsl_matrix_ulong * a, const unsigned long x); +int gsl_matrix_ulong_add_diagonal (gsl_matrix_ulong * a, const unsigned long x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_ulong_get_row(gsl_vector_ulong * v, const gsl_matrix_ulong * m, const size_t i); +int gsl_matrix_ulong_get_col(gsl_vector_ulong * v, const gsl_matrix_ulong * m, const size_t j); +int gsl_matrix_ulong_set_row(gsl_matrix_ulong * m, const size_t i, const gsl_vector_ulong * v); +int gsl_matrix_ulong_set_col(gsl_matrix_ulong * m, const size_t j, const gsl_vector_ulong * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL unsigned long gsl_matrix_ulong_get(const gsl_matrix_ulong * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_ulong_set(gsl_matrix_ulong * m, const size_t i, const size_t j, const unsigned long x); +INLINE_DECL unsigned long * gsl_matrix_ulong_ptr(gsl_matrix_ulong * m, const size_t i, const size_t j); +INLINE_DECL const unsigned long * gsl_matrix_ulong_const_ptr(const gsl_matrix_ulong * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +unsigned long +gsl_matrix_ulong_get(const gsl_matrix_ulong * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_ulong_set(gsl_matrix_ulong * m, const size_t i, const size_t j, const unsigned long x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +unsigned long * +gsl_matrix_ulong_ptr(gsl_matrix_ulong * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (unsigned long *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const unsigned long * +gsl_matrix_ulong_const_ptr(const gsl_matrix_ulong * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const unsigned long *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ushort.h new file mode 100644 index 0000000..1d9c715 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_matrix_ushort.h @@ -0,0 +1,357 @@ +/* matrix/gsl_matrix_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MATRIX_USHORT_H__ +#define __GSL_MATRIX_USHORT_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size1; + size_t size2; + size_t tda; + unsigned short * data; + gsl_block_ushort * block; + int owner; +} gsl_matrix_ushort; + +typedef struct +{ + gsl_matrix_ushort matrix; +} _gsl_matrix_ushort_view; + +typedef _gsl_matrix_ushort_view gsl_matrix_ushort_view; + +typedef struct +{ + gsl_matrix_ushort matrix; +} _gsl_matrix_ushort_const_view; + +typedef const _gsl_matrix_ushort_const_view gsl_matrix_ushort_const_view; + +/* Allocation */ + +gsl_matrix_ushort * +gsl_matrix_ushort_alloc (const size_t n1, const size_t n2); + +gsl_matrix_ushort * +gsl_matrix_ushort_calloc (const size_t n1, const size_t n2); + +gsl_matrix_ushort * +gsl_matrix_ushort_alloc_from_block (gsl_block_ushort * b, + const size_t offset, + const size_t n1, + const size_t n2, + const size_t d2); + +gsl_matrix_ushort * +gsl_matrix_ushort_alloc_from_matrix (gsl_matrix_ushort * m, + const size_t k1, + const size_t k2, + const size_t n1, + const size_t n2); + +gsl_vector_ushort * +gsl_vector_ushort_alloc_row_from_matrix (gsl_matrix_ushort * m, + const size_t i); + +gsl_vector_ushort * +gsl_vector_ushort_alloc_col_from_matrix (gsl_matrix_ushort * m, + const size_t j); + +void gsl_matrix_ushort_free (gsl_matrix_ushort * m); + +/* Views */ + +_gsl_matrix_ushort_view +gsl_matrix_ushort_submatrix (gsl_matrix_ushort * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_ushort_view +gsl_matrix_ushort_row (gsl_matrix_ushort * m, const size_t i); + +_gsl_vector_ushort_view +gsl_matrix_ushort_column (gsl_matrix_ushort * m, const size_t j); + +_gsl_vector_ushort_view +gsl_matrix_ushort_diagonal (gsl_matrix_ushort * m); + +_gsl_vector_ushort_view +gsl_matrix_ushort_subdiagonal (gsl_matrix_ushort * m, const size_t k); + +_gsl_vector_ushort_view +gsl_matrix_ushort_superdiagonal (gsl_matrix_ushort * m, const size_t k); + +_gsl_vector_ushort_view +gsl_matrix_ushort_subrow (gsl_matrix_ushort * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_ushort_view +gsl_matrix_ushort_subcolumn (gsl_matrix_ushort * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_ushort_view +gsl_matrix_ushort_view_array (unsigned short * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_ushort_view +gsl_matrix_ushort_view_array_with_tda (unsigned short * base, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_ushort_view +gsl_matrix_ushort_view_vector (gsl_vector_ushort * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_ushort_view +gsl_matrix_ushort_view_vector_with_tda (gsl_vector_ushort * v, + const size_t n1, + const size_t n2, + const size_t tda); + + +_gsl_matrix_ushort_const_view +gsl_matrix_ushort_const_submatrix (const gsl_matrix_ushort * m, + const size_t i, const size_t j, + const size_t n1, const size_t n2); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_row (const gsl_matrix_ushort * m, + const size_t i); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_column (const gsl_matrix_ushort * m, + const size_t j); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_diagonal (const gsl_matrix_ushort * m); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_subdiagonal (const gsl_matrix_ushort * m, + const size_t k); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_superdiagonal (const gsl_matrix_ushort * m, + const size_t k); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_subrow (const gsl_matrix_ushort * m, const size_t i, + const size_t offset, const size_t n); + +_gsl_vector_ushort_const_view +gsl_matrix_ushort_const_subcolumn (const gsl_matrix_ushort * m, const size_t j, + const size_t offset, const size_t n); + +_gsl_matrix_ushort_const_view +gsl_matrix_ushort_const_view_array (const unsigned short * base, + const size_t n1, + const size_t n2); + +_gsl_matrix_ushort_const_view +gsl_matrix_ushort_const_view_array_with_tda (const unsigned short * base, + const size_t n1, + const size_t n2, + const size_t tda); + +_gsl_matrix_ushort_const_view +gsl_matrix_ushort_const_view_vector (const gsl_vector_ushort * v, + const size_t n1, + const size_t n2); + +_gsl_matrix_ushort_const_view +gsl_matrix_ushort_const_view_vector_with_tda (const gsl_vector_ushort * v, + const size_t n1, + const size_t n2, + const size_t tda); + +/* Operations */ + +void gsl_matrix_ushort_set_zero (gsl_matrix_ushort * m); +void gsl_matrix_ushort_set_identity (gsl_matrix_ushort * m); +void gsl_matrix_ushort_set_all (gsl_matrix_ushort * m, unsigned short x); + +int gsl_matrix_ushort_fread (FILE * stream, gsl_matrix_ushort * m) ; +int gsl_matrix_ushort_fwrite (FILE * stream, const gsl_matrix_ushort * m) ; +int gsl_matrix_ushort_fscanf (FILE * stream, gsl_matrix_ushort * m); +int gsl_matrix_ushort_fprintf (FILE * stream, const gsl_matrix_ushort * m, const char * format); + +int gsl_matrix_ushort_memcpy(gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); +int gsl_matrix_ushort_swap(gsl_matrix_ushort * m1, gsl_matrix_ushort * m2); +int gsl_matrix_ushort_tricpy(CBLAS_UPLO_t Uplo, CBLAS_DIAG_t Diag, gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); + +int gsl_matrix_ushort_swap_rows(gsl_matrix_ushort * m, const size_t i, const size_t j); +int gsl_matrix_ushort_swap_columns(gsl_matrix_ushort * m, const size_t i, const size_t j); +int gsl_matrix_ushort_swap_rowcol(gsl_matrix_ushort * m, const size_t i, const size_t j); +int gsl_matrix_ushort_transpose (gsl_matrix_ushort * m); +int gsl_matrix_ushort_transpose_memcpy (gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); +int gsl_matrix_ushort_transpose_tricpy (CBLAS_UPLO_t Uplo_src, CBLAS_DIAG_t Diag, gsl_matrix_ushort * dest, const gsl_matrix_ushort * src); + +unsigned short gsl_matrix_ushort_max (const gsl_matrix_ushort * m); +unsigned short gsl_matrix_ushort_min (const gsl_matrix_ushort * m); +void gsl_matrix_ushort_minmax (const gsl_matrix_ushort * m, unsigned short * min_out, unsigned short * max_out); + +void gsl_matrix_ushort_max_index (const gsl_matrix_ushort * m, size_t * imax, size_t *jmax); +void gsl_matrix_ushort_min_index (const gsl_matrix_ushort * m, size_t * imin, size_t *jmin); +void gsl_matrix_ushort_minmax_index (const gsl_matrix_ushort * m, size_t * imin, size_t * jmin, size_t * imax, size_t * jmax); + +int gsl_matrix_ushort_equal (const gsl_matrix_ushort * a, const gsl_matrix_ushort * b); + +int gsl_matrix_ushort_isnull (const gsl_matrix_ushort * m); +int gsl_matrix_ushort_ispos (const gsl_matrix_ushort * m); +int gsl_matrix_ushort_isneg (const gsl_matrix_ushort * m); +int gsl_matrix_ushort_isnonneg (const gsl_matrix_ushort * m); + +unsigned short gsl_matrix_ushort_norm1 (const gsl_matrix_ushort * m); + +int gsl_matrix_ushort_add (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); +int gsl_matrix_ushort_sub (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); +int gsl_matrix_ushort_mul_elements (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); +int gsl_matrix_ushort_div_elements (gsl_matrix_ushort * a, const gsl_matrix_ushort * b); +int gsl_matrix_ushort_scale (gsl_matrix_ushort * a, const unsigned short x); +int gsl_matrix_ushort_scale_rows (gsl_matrix_ushort * a, const gsl_vector_ushort * x); +int gsl_matrix_ushort_scale_columns (gsl_matrix_ushort * a, const gsl_vector_ushort * x); +int gsl_matrix_ushort_add_constant (gsl_matrix_ushort * a, const unsigned short x); +int gsl_matrix_ushort_add_diagonal (gsl_matrix_ushort * a, const unsigned short x); + +/***********************************************************************/ +/* The functions below are obsolete */ +/***********************************************************************/ +int gsl_matrix_ushort_get_row(gsl_vector_ushort * v, const gsl_matrix_ushort * m, const size_t i); +int gsl_matrix_ushort_get_col(gsl_vector_ushort * v, const gsl_matrix_ushort * m, const size_t j); +int gsl_matrix_ushort_set_row(gsl_matrix_ushort * m, const size_t i, const gsl_vector_ushort * v); +int gsl_matrix_ushort_set_col(gsl_matrix_ushort * m, const size_t j, const gsl_vector_ushort * v); +/***********************************************************************/ + +/* inline functions if you are using GCC */ + +INLINE_DECL unsigned short gsl_matrix_ushort_get(const gsl_matrix_ushort * m, const size_t i, const size_t j); +INLINE_DECL void gsl_matrix_ushort_set(gsl_matrix_ushort * m, const size_t i, const size_t j, const unsigned short x); +INLINE_DECL unsigned short * gsl_matrix_ushort_ptr(gsl_matrix_ushort * m, const size_t i, const size_t j); +INLINE_DECL const unsigned short * gsl_matrix_ushort_const_ptr(const gsl_matrix_ushort * m, const size_t i, const size_t j); + +#ifdef HAVE_INLINE +INLINE_FUN +unsigned short +gsl_matrix_ushort_get(const gsl_matrix_ushort * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VAL("first index out of range", GSL_EINVAL, 0) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VAL("second index out of range", GSL_EINVAL, 0) ; + } + } +#endif + return m->data[i * m->tda + j] ; +} + +INLINE_FUN +void +gsl_matrix_ushort_set(gsl_matrix_ushort * m, const size_t i, const size_t j, const unsigned short x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_VOID("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_VOID("second index out of range", GSL_EINVAL) ; + } + } +#endif + m->data[i * m->tda + j] = x ; +} + +INLINE_FUN +unsigned short * +gsl_matrix_ushort_ptr(gsl_matrix_ushort * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (unsigned short *) (m->data + (i * m->tda + j)) ; +} + +INLINE_FUN +const unsigned short * +gsl_matrix_ushort_const_ptr(const gsl_matrix_ushort * m, const size_t i, const size_t j) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(1)) + { + if (i >= m->size1) + { + GSL_ERROR_NULL("first index out of range", GSL_EINVAL) ; + } + else if (j >= m->size2) + { + GSL_ERROR_NULL("second index out of range", GSL_EINVAL) ; + } + } +#endif + return (const unsigned short *) (m->data + (i * m->tda + j)) ; +} + +#endif + +__END_DECLS + +#endif /* __GSL_MATRIX_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_message.h b/ChaosDataPlayer/GSL/include/gsl/gsl_message.h new file mode 100644 index 0000000..166ff9d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_message.h @@ -0,0 +1,80 @@ +/* err/gsl_message.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MESSAGE_H__ +#define __GSL_MESSAGE_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Provide a general messaging service for client use. Messages can + * be selectively turned off at compile time by defining an + * appropriate message mask. Client code which uses the GSL_MESSAGE() + * macro must provide a mask which is or'ed with the GSL_MESSAGE_MASK. + * + * The messaging service can be completely turned off + * by defining GSL_MESSAGING_OFF. */ + +void gsl_message(const char * message, const char * file, int line, + unsigned int mask); + +#ifndef GSL_MESSAGE_MASK +#define GSL_MESSAGE_MASK 0xffffffffu /* default all messages allowed */ +#endif + +GSL_VAR unsigned int gsl_message_mask ; + +/* Provide some symolic masks for client ease of use. */ + +enum { + GSL_MESSAGE_MASK_A = 1, + GSL_MESSAGE_MASK_B = 2, + GSL_MESSAGE_MASK_C = 4, + GSL_MESSAGE_MASK_D = 8, + GSL_MESSAGE_MASK_E = 16, + GSL_MESSAGE_MASK_F = 32, + GSL_MESSAGE_MASK_G = 64, + GSL_MESSAGE_MASK_H = 128 +} ; + +#ifdef GSL_MESSAGING_OFF /* throw away messages */ +#define GSL_MESSAGE(message, mask) do { } while(0) +#else /* output all messages */ +#define GSL_MESSAGE(message, mask) \ + do { \ + if (mask & GSL_MESSAGE_MASK) \ + gsl_message (message, __FILE__, __LINE__, mask) ; \ + } while (0) +#endif + +__END_DECLS + +#endif /* __GSL_MESSAGE_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_min.h b/ChaosDataPlayer/GSL/include/gsl/gsl_min.h new file mode 100644 index 0000000..c179572 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_min.h @@ -0,0 +1,111 @@ +/* min/gsl_min.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007, 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MIN_H__ +#define __GSL_MIN_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct + { + const char *name; + size_t size; + int (*set) (void *state, gsl_function * f, double x_minimum, double f_minimum, double x_lower, double f_lower, double x_upper, double f_upper); + int (*iterate) (void *state, gsl_function * f, double * x_minimum, double * f_minimum, double * x_lower, double * f_lower, double * x_upper, double * f_upper); + } +gsl_min_fminimizer_type; + +typedef struct + { + const gsl_min_fminimizer_type * type; + gsl_function * function ; + double x_minimum ; + double x_lower ; + double x_upper ; + double f_minimum, f_lower, f_upper; + void *state; + } +gsl_min_fminimizer; + +gsl_min_fminimizer * +gsl_min_fminimizer_alloc (const gsl_min_fminimizer_type * T) ; + +void gsl_min_fminimizer_free (gsl_min_fminimizer * s); + +int gsl_min_fminimizer_set (gsl_min_fminimizer * s, + gsl_function * f, double x_minimum, + double x_lower, double x_upper); + +int gsl_min_fminimizer_set_with_values (gsl_min_fminimizer * s, + gsl_function * f, + double x_minimum, double f_minimum, + double x_lower, double f_lower, + double x_upper, double f_upper); + +int gsl_min_fminimizer_iterate (gsl_min_fminimizer * s); + +const char * gsl_min_fminimizer_name (const gsl_min_fminimizer * s); + +double gsl_min_fminimizer_x_minimum (const gsl_min_fminimizer * s); +double gsl_min_fminimizer_x_lower (const gsl_min_fminimizer * s); +double gsl_min_fminimizer_x_upper (const gsl_min_fminimizer * s); +double gsl_min_fminimizer_f_minimum (const gsl_min_fminimizer * s); +double gsl_min_fminimizer_f_lower (const gsl_min_fminimizer * s); +double gsl_min_fminimizer_f_upper (const gsl_min_fminimizer * s); + +/* Deprecated, use x_minimum instead */ +double gsl_min_fminimizer_minimum (const gsl_min_fminimizer * s); + +int +gsl_min_test_interval (double x_lower, double x_upper, double epsabs, double epsrel); + +GSL_VAR const gsl_min_fminimizer_type * gsl_min_fminimizer_goldensection; +GSL_VAR const gsl_min_fminimizer_type * gsl_min_fminimizer_brent; +GSL_VAR const gsl_min_fminimizer_type * gsl_min_fminimizer_quad_golden; + +typedef +int (*gsl_min_bracketing_function)(gsl_function *f, + double *x_minimum,double * f_minimum, + double *x_lower, double * f_lower, + double *x_upper, double * f_upper, + size_t eval_max); + +int +gsl_min_find_bracket(gsl_function *f,double *x_minimum,double * f_minimum, + double *x_lower, double * f_lower, + double *x_upper, double * f_upper, + size_t eval_max); + +__END_DECLS + +#endif /* __GSL_MIN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_minmax.h b/ChaosDataPlayer/GSL/include/gsl/gsl_minmax.h new file mode 100644 index 0000000..0d9a836 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_minmax.h @@ -0,0 +1,102 @@ +/* gsl_minmax.h + * + * Copyright (C) 2008 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MINMAX_H__ +#define __GSL_MINMAX_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Define MAX and MIN macros/functions if they don't exist. */ + +/* plain old macros for general use */ +#define GSL_MAX(a,b) ((a) > (b) ? (a) : (b)) +#define GSL_MIN(a,b) ((a) < (b) ? (a) : (b)) + +/* function versions of the above, in case they are needed */ +double gsl_max (double a, double b); +double gsl_min (double a, double b); + +/* inline-friendly strongly typed versions */ +#ifdef HAVE_INLINE + +INLINE_FUN int GSL_MAX_INT (int a, int b); +INLINE_FUN int GSL_MIN_INT (int a, int b); +INLINE_FUN double GSL_MAX_DBL (double a, double b); +INLINE_FUN double GSL_MIN_DBL (double a, double b); +INLINE_FUN long double GSL_MAX_LDBL (long double a, long double b); +INLINE_FUN long double GSL_MIN_LDBL (long double a, long double b); + +INLINE_FUN int +GSL_MAX_INT (int a, int b) +{ + return GSL_MAX (a, b); +} + +INLINE_FUN int +GSL_MIN_INT (int a, int b) +{ + return GSL_MIN (a, b); +} + +INLINE_FUN double +GSL_MAX_DBL (double a, double b) +{ + return GSL_MAX (a, b); +} + +INLINE_FUN double +GSL_MIN_DBL (double a, double b) +{ + return GSL_MIN (a, b); +} + +INLINE_FUN long double +GSL_MAX_LDBL (long double a, long double b) +{ + return GSL_MAX (a, b); +} + +INLINE_FUN long double +GSL_MIN_LDBL (long double a, long double b) +{ + return GSL_MIN (a, b); +} +#else +#define GSL_MAX_INT(a,b) GSL_MAX(a,b) +#define GSL_MIN_INT(a,b) GSL_MIN(a,b) +#define GSL_MAX_DBL(a,b) GSL_MAX(a,b) +#define GSL_MIN_DBL(a,b) GSL_MIN(a,b) +#define GSL_MAX_LDBL(a,b) GSL_MAX(a,b) +#define GSL_MIN_LDBL(a,b) GSL_MIN(a,b) +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_POW_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_mode.h b/ChaosDataPlayer/GSL/include/gsl/gsl_mode.h new file mode 100644 index 0000000..c8e5d55 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_mode.h @@ -0,0 +1,88 @@ +/* gsl_mode.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: B. Gough and G. Jungman */ + +#ifndef __GSL_MODE_H__ +#define __GSL_MODE_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Some functions can take a mode argument. This + * is a rough method to do things like control + * the precision of the algorithm. This mainly + * occurs in special functions, but we figured + * it was ok to have a general facility. + * + * The mode type is 32-bit field. Most of + * the fields are currently unused. Users + * '|' various predefined constants to get + * a desired mode. + */ +typedef unsigned int gsl_mode_t; + + +/* Here are the predefined constants. + * Note that the precision constants + * are special because they are used + * to index arrays, so do not change + * them. The precision information is + * in the low order 3 bits of gsl_mode_t + * (the third bit is currently unused). + */ + +/* Note that "0" is double precision, + * so that you get that by default if + * you forget a flag. + */ +#define GSL_PREC_DOUBLE 0 +#define GSL_PREC_SINGLE 1 +#define GSL_PREC_APPROX 2 + +#ifdef HAVE_INLINE +INLINE_FUN unsigned int GSL_MODE_PREC(gsl_mode_t mt); + +INLINE_FUN unsigned int +GSL_MODE_PREC(gsl_mode_t mt) +{ return (mt & (unsigned int)7); } +#else /* HAVE_INLINE */ +#define GSL_MODE_PREC(mt) ((mt) & (unsigned int)7) +#endif /* HAVE_INLINE */ + + +/* Here are some predefined generic modes. + */ +#define GSL_MODE_DEFAULT 0 + + +__END_DECLS + +#endif /* __GSL_MODE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_monte.h b/ChaosDataPlayer/GSL/include/gsl/gsl_monte.h new file mode 100644 index 0000000..614c41b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_monte.h @@ -0,0 +1,57 @@ +/* monte/gsl_monte.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Some things common to all the Monte-Carlo implementations */ +/* Author: MJB */ + +#ifndef __GSL_MONTE_H__ +#define __GSL_MONTE_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Hide the function type in a typedef so that we can use it in all our + integration functions, and make it easy to change things. +*/ + +struct gsl_monte_function_struct { + double (*f)(double * x_array, size_t dim, void * params); + size_t dim; + void * params; +}; + +typedef struct gsl_monte_function_struct gsl_monte_function; + +#define GSL_MONTE_FN_EVAL(F,x) (*((F)->f))(x,(F)->dim,(F)->params) + + +__END_DECLS + +#endif /* __GSL_MONTE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_monte_miser.h b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_miser.h new file mode 100644 index 0000000..5940396 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_miser.h @@ -0,0 +1,97 @@ +/* monte/gsl_monte_miser.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth + * Copyright (C) 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: MJB */ + +#ifndef __GSL_MONTE_MISER_H__ +#define __GSL_MONTE_MISER_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + size_t min_calls; + size_t min_calls_per_bisection; + double dither; + double estimate_frac; + double alpha; + size_t dim; + int estimate_style; + int depth; + int verbose; + double * x; + double * xmid; + double * sigma_l; + double * sigma_r; + double * fmax_l; + double * fmax_r; + double * fmin_l; + double * fmin_r; + double * fsum_l; + double * fsum_r; + double * fsum2_l; + double * fsum2_r; + size_t * hits_l; + size_t * hits_r; +} gsl_monte_miser_state; + +int gsl_monte_miser_integrate(gsl_monte_function * f, + const double xl[], const double xh[], + size_t dim, size_t calls, + gsl_rng *r, + gsl_monte_miser_state* state, + double *result, double *abserr); + +gsl_monte_miser_state* gsl_monte_miser_alloc(size_t dim); + +int gsl_monte_miser_init(gsl_monte_miser_state* state); + +void gsl_monte_miser_free(gsl_monte_miser_state* state); + +typedef struct { + double estimate_frac; + size_t min_calls; + size_t min_calls_per_bisection; + double alpha; + double dither; +} gsl_monte_miser_params; + +void gsl_monte_miser_params_get (const gsl_monte_miser_state * state, + gsl_monte_miser_params * params); + +void gsl_monte_miser_params_set (gsl_monte_miser_state * state, + const gsl_monte_miser_params * params); + +__END_DECLS + +#endif /* __GSL_MONTE_MISER_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_monte_plain.h b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_plain.h new file mode 100644 index 0000000..c4745b9 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_plain.h @@ -0,0 +1,65 @@ +/* monte/gsl_monte_plain.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Plain Monte-Carlo. */ + +/* Author: MJB */ + +#ifndef __GSL_MONTE_PLAIN_H__ +#define __GSL_MONTE_PLAIN_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + size_t dim; + double *x; +} gsl_monte_plain_state; + +int +gsl_monte_plain_integrate (const gsl_monte_function * f, + const double xl[], const double xu[], + const size_t dim, + const size_t calls, + gsl_rng * r, + gsl_monte_plain_state * state, + double *result, double *abserr); + +gsl_monte_plain_state* gsl_monte_plain_alloc(size_t dim); + +int gsl_monte_plain_init(gsl_monte_plain_state* state); + +void gsl_monte_plain_free (gsl_monte_plain_state* state); + +__END_DECLS + +#endif /* __GSL_MONTE_PLAIN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_monte_vegas.h b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_vegas.h new file mode 100644 index 0000000..0942c04 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_monte_vegas.h @@ -0,0 +1,125 @@ +/* monte/gsl_monte_vegas.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael Booth + * Copyright (C) 2009 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* header for the gsl "vegas" routines. Mike Booth, May 1998 */ + +#ifndef __GSL_MONTE_VEGAS_H__ +#define __GSL_MONTE_VEGAS_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +enum {GSL_VEGAS_MODE_IMPORTANCE = 1, + GSL_VEGAS_MODE_IMPORTANCE_ONLY = 0, + GSL_VEGAS_MODE_STRATIFIED = -1}; + +typedef struct { + /* grid */ + size_t dim; + size_t bins_max; + unsigned int bins; + unsigned int boxes; /* these are both counted along the axes */ + double * xi; + double * xin; + double * delx; + double * weight; + double vol; + + double * x; + int * bin; + int * box; + + /* distribution */ + double * d; + + /* control variables */ + double alpha; + int mode; + int verbose; + unsigned int iterations; + int stage; + + /* scratch variables preserved between calls to vegas1/2/3 */ + double jac; + double wtd_int_sum; + double sum_wgts; + double chi_sum; + double chisq; + + double result; + double sigma; + + unsigned int it_start; + unsigned int it_num; + unsigned int samples; + unsigned int calls_per_box; + + FILE * ostream; + +} gsl_monte_vegas_state; + +int gsl_monte_vegas_integrate(gsl_monte_function * f, + double xl[], double xu[], + size_t dim, size_t calls, + gsl_rng * r, + gsl_monte_vegas_state *state, + double* result, double* abserr); + +gsl_monte_vegas_state* gsl_monte_vegas_alloc(size_t dim); + +int gsl_monte_vegas_init(gsl_monte_vegas_state* state); + +void gsl_monte_vegas_free (gsl_monte_vegas_state* state); + +double gsl_monte_vegas_chisq (const gsl_monte_vegas_state* state); +void gsl_monte_vegas_runval (const gsl_monte_vegas_state* state, double * result, double * sigma); + +typedef struct { + double alpha; + size_t iterations; + int stage; + int mode; + int verbose; + FILE * ostream; +} gsl_monte_vegas_params; + +void gsl_monte_vegas_params_get (const gsl_monte_vegas_state * state, + gsl_monte_vegas_params * params); + +void gsl_monte_vegas_params_set (gsl_monte_vegas_state * state, + const gsl_monte_vegas_params * params); + +__END_DECLS + +#endif /* __GSL_MONTE_VEGAS_H__ */ + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_movstat.h b/ChaosDataPlayer/GSL/include/gsl/gsl_movstat.h new file mode 100644 index 0000000..54f4fce --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_movstat.h @@ -0,0 +1,138 @@ +/* movstat/gsl_movstat.h + * + * Copyright (C) 2018 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MOVSTAT_H__ +#define __GSL_MOVSTAT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum +{ + GSL_MOVSTAT_END_PADZERO, + GSL_MOVSTAT_END_PADVALUE, + GSL_MOVSTAT_END_TRUNCATE +} gsl_movstat_end_t; + +/* accumulator struct + * size - return number of bytes needed for accumulator with maximum of n elements + * init - initialize accumulator state + * insert - insert a single sample into accumulator; if there are already n + * samples in accumulator, oldest sample is overwritten + * delete_oldest - delete oldest sample from accumulator + * get - return accumulated value + */ +typedef struct +{ + size_t (*size) (const size_t n); + int (*init) (const size_t n, void * vstate); + int (*insert) (const double x, void * vstate); + int (*delete_oldest) (void * vstate); + int (*get) (void * params, double * result, const void * vstate); +} gsl_movstat_accum; + +typedef struct +{ + double (* function) (const size_t n, double x[], void * params); + void * params; +} gsl_movstat_function; + +#define GSL_MOVSTAT_FN_EVAL(F,n,x) (*((F)->function))((n),(x),(F)->params) + +/* workspace for moving window statistics */ + +typedef struct +{ + size_t H; /* number of previous samples in window */ + size_t J; /* number of after samples in window */ + size_t K; /* window size K = H + J + 1 */ + double *work; /* workspace, size K */ + void *state; /* state workspace for various accumulators */ + size_t state_size; /* bytes allocated for 'state' */ +} gsl_movstat_workspace; + +/* alloc.c */ + +gsl_movstat_workspace *gsl_movstat_alloc(const size_t K); +gsl_movstat_workspace *gsl_movstat_alloc2(const size_t H, const size_t J); +gsl_movstat_workspace *gsl_movstat_alloc_with_size(const size_t accum_state_size, const size_t H, const size_t J); +void gsl_movstat_free(gsl_movstat_workspace * w); + +/* apply.c */ +int gsl_movstat_apply_accum(const gsl_movstat_end_t endtype, const gsl_vector * x, + const gsl_movstat_accum * accum, void * accum_params, + gsl_vector * y, gsl_vector * z, + gsl_movstat_workspace * w); +int gsl_movstat_apply(const gsl_movstat_end_t endtype, const gsl_movstat_function * F, + const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); + +/* fill.c */ +size_t gsl_movstat_fill(const gsl_movstat_end_t endtype, const gsl_vector * x, const size_t idx, + const size_t H, const size_t J, double * window); + +int gsl_movstat_mean(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_variance(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_sd(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_median(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_min(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_max(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); +int gsl_movstat_minmax(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y_min, gsl_vector * y_max, gsl_movstat_workspace * w); +int gsl_movstat_mad0(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * xmedian, + gsl_vector * xmad, gsl_movstat_workspace * w); +int gsl_movstat_mad(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * xmedian, + gsl_vector * xmad, gsl_movstat_workspace * w); +int gsl_movstat_qqr(const gsl_movstat_end_t endtype, const gsl_vector * x, const double q, + gsl_vector * xqqr, gsl_movstat_workspace * w); +int gsl_movstat_Sn(const gsl_movstat_end_t endtype, const gsl_vector * x, + gsl_vector * xscale, gsl_movstat_workspace * w); +int gsl_movstat_Qn(const gsl_movstat_end_t endtype, const gsl_vector * x, + gsl_vector * xscale, gsl_movstat_workspace * w); +int gsl_movstat_sum(const gsl_movstat_end_t endtype, const gsl_vector * x, gsl_vector * y, gsl_movstat_workspace * w); + +/* accumulator variables */ + +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_mad; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_max; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_mean; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_median; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_min; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_minmax; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_sd; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_Sn; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_sum; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_Qn; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_qqr; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_userfunc; +GSL_VAR const gsl_movstat_accum * gsl_movstat_accum_variance; + +__END_DECLS + +#endif /* __GSL_MOVSTAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multifit.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit.h new file mode 100644 index 0000000..53961ee --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit.h @@ -0,0 +1,388 @@ +/* multifit/gsl_multifit.h + * + * Copyright (C) 2000, 2007, 2010 Brian Gough + * Copyright (C) 2013, Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTIFIT_H__ +#define __GSL_MULTIFIT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t nmax; /* maximum number of observations */ + size_t pmax; /* maximum number of parameters */ + size_t n; /* number of observations in current SVD decomposition */ + size_t p; /* number of parameters in current SVD decomposition */ + gsl_matrix * A; /* least squares matrix for SVD, n-by-p */ + gsl_matrix * Q; + gsl_matrix * QSI; + gsl_vector * S; + gsl_vector * t; + gsl_vector * xt; + gsl_vector * D; + double rcond; /* reciprocal condition number */ +} +gsl_multifit_linear_workspace; + +gsl_multifit_linear_workspace * +gsl_multifit_linear_alloc (const size_t n, const size_t p); + +void +gsl_multifit_linear_free (gsl_multifit_linear_workspace * w); + +int +gsl_multifit_linear (const gsl_matrix * X, + const gsl_vector * y, + gsl_vector * c, + gsl_matrix * cov, + double * chisq, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_tsvd (const gsl_matrix * X, + const gsl_vector * y, + const double tol, + gsl_vector * c, + gsl_matrix * cov, + double * chisq, + size_t * rank, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_svd (const gsl_matrix * X, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_bsvd (const gsl_matrix * X, + gsl_multifit_linear_workspace * work); + +size_t +gsl_multifit_linear_rank(const double tol, const gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_solve (const double lambda, + const gsl_matrix * X, + const gsl_vector * y, + gsl_vector * c, + double *rnorm, + double *snorm, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_applyW(const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_matrix * WX, + gsl_vector * Wy); + +int +gsl_multifit_linear_stdform1 (const gsl_vector * L, + const gsl_matrix * X, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_wstdform1 (const gsl_vector * L, + const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_L_decomp (gsl_matrix * L, gsl_vector * tau); + +int +gsl_multifit_linear_stdform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_matrix * M, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_wstdform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_matrix * M, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_genform1 (const gsl_vector * L, + const gsl_vector * cs, + gsl_vector * c, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_genform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * y, + const gsl_vector * cs, + const gsl_matrix * M, + gsl_vector * c, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_wgenform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + const gsl_vector * cs, + const gsl_matrix * M, + gsl_vector * c, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_lreg (const double smin, const double smax, + gsl_vector * reg_param); + +int +gsl_multifit_linear_lcurve (const gsl_vector * y, + gsl_vector * reg_param, + gsl_vector * rho, gsl_vector * eta, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_lcurvature (const gsl_vector * y, + const gsl_vector * reg_param, + const gsl_vector * rho, + const gsl_vector * eta, + gsl_vector * kappa, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_lcorner(const gsl_vector *rho, + const gsl_vector *eta, + size_t *idx); + +int +gsl_multifit_linear_lcorner2(const gsl_vector *reg_param, + const gsl_vector *eta, + size_t *idx); + +int +gsl_multifit_linear_Lk(const size_t p, const size_t k, gsl_matrix *L); + +int +gsl_multifit_linear_Lsobolev(const size_t p, const size_t kmax, + const gsl_vector *alpha, gsl_matrix *L, + gsl_multifit_linear_workspace *work); + +int +gsl_multifit_wlinear (const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_vector * c, + gsl_matrix * cov, + double * chisq, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_wlinear_tsvd (const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + const double tol, + gsl_vector * c, + gsl_matrix * cov, + double * chisq, + size_t * rank, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_wlinear_svd (const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + double tol, + size_t * rank, + gsl_vector * c, + gsl_matrix * cov, + double *chisq, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_wlinear_usvd (const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + double tol, + size_t * rank, + gsl_vector * c, + gsl_matrix * cov, + double *chisq, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_est (const gsl_vector * x, + const gsl_vector * c, + const gsl_matrix * cov, double *y, double *y_err); + +double +gsl_multifit_linear_rcond (const gsl_multifit_linear_workspace * w); + +int +gsl_multifit_linear_residuals (const gsl_matrix *X, const gsl_vector *y, + const gsl_vector *c, gsl_vector *r); + +/* gcv.c */ +int +gsl_multifit_linear_gcv_init(const gsl_vector * y, + gsl_vector * reg_param, + gsl_vector * UTy, + double * delta0, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_gcv_curve(const gsl_vector * reg_param, + const gsl_vector * UTy, + const double delta0, + gsl_vector * G, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_gcv_min(const gsl_vector * reg_param, + const gsl_vector * UTy, + const gsl_vector * G, + const double delta0, + double * lambda, + gsl_multifit_linear_workspace * work); + +double +gsl_multifit_linear_gcv_calc(const double lambda, + const gsl_vector * UTy, + const double delta0, + gsl_multifit_linear_workspace * work); + +int +gsl_multifit_linear_gcv(const gsl_vector * y, + gsl_vector * reg_param, + gsl_vector * G, + double * lambda, + double * G_lambda, + gsl_multifit_linear_workspace * work); + +typedef struct +{ + const char * name; /* method name */ + int (*wfun)(const gsl_vector *r, gsl_vector *w); + int (*psi_deriv)(const gsl_vector *r, gsl_vector *dpsi); + double tuning_default; /* default tuning constant */ +} gsl_multifit_robust_type; + +typedef struct +{ + double sigma_ols; /* OLS estimate of sigma */ + double sigma_mad; /* MAD estimate of sigma */ + double sigma_rob; /* robust estimate of sigma */ + double sigma; /* final estimate of sigma */ + double Rsq; /* R^2 coefficient of determination */ + double adj_Rsq; /* degree of freedom adjusted R^2 */ + double rmse; /* root mean squared error */ + double sse; /* residual sum of squares */ + size_t dof; /* degrees of freedom */ + size_t numit; /* number of iterations */ + gsl_vector *weights; /* final weights */ + gsl_vector *r; /* final residuals y - X c */ +} gsl_multifit_robust_stats; + +typedef struct +{ + size_t n; /* number of observations */ + size_t p; /* number of parameters */ + size_t numit; /* number of iterations */ + size_t maxiter; /* maximum iterations */ + const gsl_multifit_robust_type *type; + double tune; /* tuning parameter */ + + gsl_vector *r; /* residuals at current iteration */ + gsl_vector *weights; /* weights at current iteration */ + gsl_vector *c_prev; /* coefficients from previous iteration */ + gsl_vector *resfac; /* multiplicative factors for residuals */ + + gsl_vector *psi; /* psi(r) */ + gsl_vector *dpsi; /* psi'(r) */ + + gsl_matrix *QSI; /* Q S^{-1} of original matrix X */ + gsl_vector *D; /* balancing parameters of original matrix X */ + + gsl_vector *workn; /* workspace of length n */ + + gsl_multifit_robust_stats stats; /* various statistics */ + + gsl_multifit_linear_workspace *multifit_p; +} gsl_multifit_robust_workspace; + +/* available types */ +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_default; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_bisquare; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_cauchy; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_fair; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_huber; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_ols; +GSL_VAR const gsl_multifit_robust_type * gsl_multifit_robust_welsch; + +gsl_multifit_robust_workspace *gsl_multifit_robust_alloc(const gsl_multifit_robust_type *T, + const size_t n, const size_t p); +void gsl_multifit_robust_free(gsl_multifit_robust_workspace *w); +int gsl_multifit_robust_tune(const double tune, + gsl_multifit_robust_workspace *w); +int gsl_multifit_robust_maxiter(const size_t maxiter, + gsl_multifit_robust_workspace *w); +const char *gsl_multifit_robust_name(const gsl_multifit_robust_workspace *w); +gsl_multifit_robust_stats gsl_multifit_robust_statistics(const gsl_multifit_robust_workspace *w); +int gsl_multifit_robust_weights(const gsl_vector *r, gsl_vector *wts, + gsl_multifit_robust_workspace *w); +int gsl_multifit_robust(const gsl_matrix * X, const gsl_vector * y, + gsl_vector * c, gsl_matrix *cov, + gsl_multifit_robust_workspace *w); +int gsl_multifit_robust_est(const gsl_vector * x, const gsl_vector * c, + const gsl_matrix * cov, double *y, double *y_err); +int gsl_multifit_robust_residuals(const gsl_matrix * X, + const gsl_vector * y, + const gsl_vector * c, gsl_vector * r, + gsl_multifit_robust_workspace * w); + +__END_DECLS + +#endif /* __GSL_MULTIFIT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlin.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlin.h new file mode 100644 index 0000000..b0dd06e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlin.h @@ -0,0 +1,275 @@ +/* multifit_nlin/gsl_multifit_nlin.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTIFIT_NLIN_H__ +#define __GSL_MULTIFIT_NLIN_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_multifit_gradient (const gsl_matrix * J, const gsl_vector * f, + gsl_vector * g); + +int gsl_multifit_covar (const gsl_matrix * J, const double epsrel, gsl_matrix * covar); +int gsl_multifit_covar_QRPT (gsl_matrix * r, gsl_permutation * perm, + const double epsrel, gsl_matrix * covar); + + +/* Definition of vector-valued functions with parameters based on gsl_vector */ + +struct gsl_multifit_function_struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + size_t n; /* number of functions */ + size_t p; /* number of independent variables */ + void * params; +}; + +typedef struct gsl_multifit_function_struct gsl_multifit_function ; + +#define GSL_MULTIFIT_FN_EVAL(F,x,y) (*((F)->f))(x,(F)->params,(y)) + +typedef struct + { + const char *name; + size_t size; + int (*alloc) (void *state, size_t n, size_t p); + int (*set) (void *state, gsl_multifit_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); + int (*iterate) (void *state, gsl_multifit_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); + void (*free) (void *state); + } +gsl_multifit_fsolver_type; + +typedef struct + { + const gsl_multifit_fsolver_type * type; + gsl_multifit_function * function ; + gsl_vector * x ; + gsl_vector * f ; + gsl_vector * dx ; + void *state; + } +gsl_multifit_fsolver; + +gsl_multifit_fsolver * +gsl_multifit_fsolver_alloc (const gsl_multifit_fsolver_type * T, + size_t n, size_t p); + +void gsl_multifit_fsolver_free (gsl_multifit_fsolver * s); + +int gsl_multifit_fsolver_set (gsl_multifit_fsolver * s, + gsl_multifit_function * f, + const gsl_vector * x); + +int gsl_multifit_fsolver_iterate (gsl_multifit_fsolver * s); + +int gsl_multifit_fsolver_driver (gsl_multifit_fsolver * s, + const size_t maxiter, + const double epsabs, const double epsrel); + +const char * gsl_multifit_fsolver_name (const gsl_multifit_fsolver * s); +gsl_vector * gsl_multifit_fsolver_position (const gsl_multifit_fsolver * s); + +/* Definition of vector-valued functions and gradient with parameters + based on gsl_vector */ + +struct gsl_multifit_function_fdf_struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + int (* df) (const gsl_vector * x, void * params, gsl_matrix * df); + int (* fdf) (const gsl_vector * x, void * params, gsl_vector * f, gsl_matrix *df); + size_t n; /* number of functions */ + size_t p; /* number of independent variables */ + void * params; /* user parameters */ + size_t nevalf; /* number of function evaluations */ + size_t nevaldf; /* number of Jacobian evaluations */ +}; + +typedef struct gsl_multifit_function_fdf_struct gsl_multifit_function_fdf ; + +typedef struct + { + const char *name; + size_t size; + int (*alloc) (void *state, size_t n, size_t p); + int (*set) (void *state, const gsl_vector * wts, + gsl_multifit_function_fdf * fdf, gsl_vector * x, + gsl_vector * f, gsl_vector * dx); + int (*iterate) (void *state, const gsl_vector * wts, + gsl_multifit_function_fdf * fdf, gsl_vector * x, + gsl_vector * f, gsl_vector * dx); + int (*gradient) (void *state, gsl_vector * g); + int (*jac) (void *state, gsl_matrix * J); + void (*free) (void *state); + } +gsl_multifit_fdfsolver_type; + +typedef struct + { + const gsl_multifit_fdfsolver_type * type; + gsl_multifit_function_fdf * fdf ; + gsl_vector * x; /* parameter values x */ + gsl_vector * f; /* residual vector f(x) */ + gsl_vector * dx; /* step dx */ + gsl_vector * g; /* gradient J^T f */ + gsl_vector * sqrt_wts; /* sqrt(wts) */ + size_t niter; /* number of iterations performed */ + void *state; + } +gsl_multifit_fdfsolver; + + +gsl_multifit_fdfsolver * +gsl_multifit_fdfsolver_alloc (const gsl_multifit_fdfsolver_type * T, + size_t n, size_t p); + +int +gsl_multifit_fdfsolver_set (gsl_multifit_fdfsolver * s, + gsl_multifit_function_fdf * fdf, + const gsl_vector * x); +int gsl_multifit_fdfsolver_wset (gsl_multifit_fdfsolver * s, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const gsl_vector * wts); + +int +gsl_multifit_fdfsolver_iterate (gsl_multifit_fdfsolver * s); + +int gsl_multifit_fdfsolver_driver (gsl_multifit_fdfsolver * s, + const size_t maxiter, + const double xtol, + const double gtol, + const double ftol, + int *info); + +int gsl_multifit_fdfsolver_jac (gsl_multifit_fdfsolver * s, + gsl_matrix * J); + +void +gsl_multifit_fdfsolver_free (gsl_multifit_fdfsolver * s); + +const char * gsl_multifit_fdfsolver_name (const gsl_multifit_fdfsolver * s); +gsl_vector * gsl_multifit_fdfsolver_position (const gsl_multifit_fdfsolver * s); +gsl_vector * gsl_multifit_fdfsolver_residual (const gsl_multifit_fdfsolver * s); +size_t gsl_multifit_fdfsolver_niter (const gsl_multifit_fdfsolver * s); +int gsl_multifit_eval_wf(gsl_multifit_function_fdf *fdf, + const gsl_vector *x, const gsl_vector *wts, + gsl_vector *y); +int gsl_multifit_eval_wdf(gsl_multifit_function_fdf *fdf, + const gsl_vector *x, const gsl_vector *wts, + gsl_matrix *dy); + +int gsl_multifit_fdfsolver_test (const gsl_multifit_fdfsolver * s, + const double xtol, + const double gtol, + const double ftol, int *info); +int gsl_multifit_test_delta (const gsl_vector * dx, const gsl_vector * x, + double epsabs, double epsrel); + +int gsl_multifit_test_gradient (const gsl_vector * g, double epsabs); + +int gsl_multifit_fdfsolver_dif_df(const gsl_vector *x, + const gsl_vector *wts, + gsl_multifit_function_fdf *fdf, + const gsl_vector *f, gsl_matrix *J); +int gsl_multifit_fdfsolver_dif_fdf(const gsl_vector *x, gsl_multifit_function_fdf *fdf, + gsl_vector *f, gsl_matrix *J); + +typedef struct +{ + size_t n; /* number of (original) residuals */ + size_t p; /* number of model parameters */ + double lambda; /* damping parameter */ + const gsl_vector *L_diag; /* diagonal damping matrix or NULL */ + const gsl_matrix *L; /* general damping matrix or NULL */ + gsl_vector *f; /* function values for finite diff J */ + gsl_vector *wts; /* weight vector for augmented system */ + gsl_multifit_fdfsolver * s; + gsl_multifit_function_fdf *fdf; /* user defined fdf */ + gsl_multifit_function_fdf fdftik; /* Tikhonov modified fdf */ +} gsl_multifit_fdfridge; + +gsl_multifit_fdfridge * +gsl_multifit_fdfridge_alloc (const gsl_multifit_fdfsolver_type * T, + const size_t n, const size_t p); +void gsl_multifit_fdfridge_free(gsl_multifit_fdfridge *work); +const char *gsl_multifit_fdfridge_name(const gsl_multifit_fdfridge * w); +gsl_vector *gsl_multifit_fdfridge_position (const gsl_multifit_fdfridge * w); +gsl_vector *gsl_multifit_fdfridge_residual (const gsl_multifit_fdfridge * w); +size_t gsl_multifit_fdfridge_niter (const gsl_multifit_fdfridge * w); +int gsl_multifit_fdfridge_set (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const double lambda); +int gsl_multifit_fdfridge_wset (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const double lambda, + const gsl_vector * wts); +int gsl_multifit_fdfridge_set2 (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const gsl_vector * lambda); +int gsl_multifit_fdfridge_wset2 (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const gsl_vector * lambda, + const gsl_vector * wts); +int gsl_multifit_fdfridge_set3 (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const gsl_matrix * L); +int gsl_multifit_fdfridge_wset3 (gsl_multifit_fdfridge * w, + gsl_multifit_function_fdf * f, + const gsl_vector * x, + const gsl_matrix * L, + const gsl_vector * wts); +int gsl_multifit_fdfridge_iterate (gsl_multifit_fdfridge * w); +int gsl_multifit_fdfridge_driver (gsl_multifit_fdfridge * w, + const size_t maxiter, + const double xtol, + const double gtol, + const double ftol, + int *info); + +/* extern const gsl_multifit_fsolver_type * gsl_multifit_fsolver_gradient; */ + +GSL_VAR const gsl_multifit_fdfsolver_type * gsl_multifit_fdfsolver_lmsder; +GSL_VAR const gsl_multifit_fdfsolver_type * gsl_multifit_fdfsolver_lmder; +GSL_VAR const gsl_multifit_fdfsolver_type * gsl_multifit_fdfsolver_lmniel; + +__END_DECLS + +#endif /* __GSL_MULTIFIT_NLIN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlinear.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlinear.h new file mode 100644 index 0000000..e8042df --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multifit_nlinear.h @@ -0,0 +1,304 @@ +/* multifit_nlinear/gsl_multifit_nlinear.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * Copyright (C) 2015, 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTIFIT_NLINEAR_H__ +#define __GSL_MULTIFIT_NLINEAR_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum +{ + GSL_MULTIFIT_NLINEAR_FWDIFF, + GSL_MULTIFIT_NLINEAR_CTRDIFF +} gsl_multifit_nlinear_fdtype; + +/* Definition of vector-valued functions and gradient with parameters + based on gsl_vector */ + +typedef struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + int (* df) (const gsl_vector * x, void * params, gsl_matrix * df); + int (* fvv) (const gsl_vector * x, const gsl_vector * v, void * params, + gsl_vector * fvv); + size_t n; /* number of functions */ + size_t p; /* number of independent variables */ + void * params; /* user parameters */ + size_t nevalf; /* number of function evaluations */ + size_t nevaldf; /* number of Jacobian evaluations */ + size_t nevalfvv; /* number of fvv evaluations */ +} gsl_multifit_nlinear_fdf; + +/* trust region subproblem method */ +typedef struct +{ + const char *name; + void * (*alloc) (const void * params, const size_t n, const size_t p); + int (*init) (const void * vtrust_state, void * vstate); + int (*preloop) (const void * vtrust_state, void * vstate); + int (*step) (const void * vtrust_state, const double delta, + gsl_vector * dx, void * vstate); + int (*preduction) (const void * vtrust_state, const gsl_vector * dx, + double * pred, void * vstate); + void (*free) (void * vstate); +} gsl_multifit_nlinear_trs; + +/* scaling matrix specification */ +typedef struct +{ + const char *name; + int (*init) (const gsl_matrix * J, gsl_vector * diag); + int (*update) (const gsl_matrix * J, gsl_vector * diag); +} gsl_multifit_nlinear_scale; + +/* + * linear least squares solvers - there are three steps to + * solving a least squares problem using a trust region + * method: + * + * 1. init: called once per iteration when a new Jacobian matrix + * is computed; perform factorization of Jacobian (qr,svd) + * or form normal equations matrix (cholesky) + * 2. presolve: called each time a new LM parameter value mu is available; + * used for cholesky method in order to factor + * the (J^T J + mu D^T D) matrix + * 3. solve: solve the least square system for a given rhs + */ +typedef struct +{ + const char *name; + void * (*alloc) (const size_t n, const size_t p); + int (*init) (const void * vtrust_state, void * vstate); + int (*presolve) (const double mu, const void * vtrust_state, void * vstate); + int (*solve) (const gsl_vector * f, gsl_vector * x, + const void * vtrust_state, void * vstate); + int (*rcond) (double * rcond, void * vstate); + void (*free) (void * vstate); +} gsl_multifit_nlinear_solver; + +/* tunable parameters */ +typedef struct +{ + const gsl_multifit_nlinear_trs *trs; /* trust region subproblem method */ + const gsl_multifit_nlinear_scale *scale; /* scaling method */ + const gsl_multifit_nlinear_solver *solver; /* solver method */ + gsl_multifit_nlinear_fdtype fdtype; /* finite difference method */ + double factor_up; /* factor for increasing trust radius */ + double factor_down; /* factor for decreasing trust radius */ + double avmax; /* max allowed |a|/|v| */ + double h_df; /* step size for finite difference Jacobian */ + double h_fvv; /* step size for finite difference fvv */ +} gsl_multifit_nlinear_parameters; + +typedef struct +{ + const char *name; + void * (*alloc) (const gsl_multifit_nlinear_parameters * params, + const size_t n, const size_t p); + int (*init) (void * state, const gsl_vector * wts, + gsl_multifit_nlinear_fdf * fdf, const gsl_vector * x, + gsl_vector * f, gsl_matrix * J, gsl_vector * g); + int (*iterate) (void * state, const gsl_vector * wts, + gsl_multifit_nlinear_fdf * fdf, gsl_vector * x, + gsl_vector * f, gsl_matrix * J, gsl_vector * g, + gsl_vector * dx); + int (*rcond) (double * rcond, void * state); + double (*avratio) (void * state); + void (*free) (void * state); +} gsl_multifit_nlinear_type; + +/* current state passed to low-level trust region algorithms */ +typedef struct +{ + const gsl_vector * x; /* parameter values x */ + const gsl_vector * f; /* residual vector f(x) */ + const gsl_vector * g; /* gradient J^T f */ + const gsl_matrix * J; /* Jacobian J(x) */ + const gsl_vector * diag; /* scaling matrix D */ + const gsl_vector * sqrt_wts; /* sqrt(diag(W)) or NULL for unweighted */ + const double *mu; /* LM parameter */ + const gsl_multifit_nlinear_parameters * params; + void *solver_state; /* workspace for linear least squares solver */ + gsl_multifit_nlinear_fdf * fdf; + double *avratio; /* |a| / |v| */ +} gsl_multifit_nlinear_trust_state; + +typedef struct +{ + const gsl_multifit_nlinear_type * type; + gsl_multifit_nlinear_fdf * fdf ; + gsl_vector * x; /* parameter values x */ + gsl_vector * f; /* residual vector f(x) */ + gsl_vector * dx; /* step dx */ + gsl_vector * g; /* gradient J^T f */ + gsl_matrix * J; /* Jacobian J(x) */ + gsl_vector * sqrt_wts_work; /* sqrt(W) */ + gsl_vector * sqrt_wts; /* ptr to sqrt_wts_work, or NULL if not using weights */ + size_t niter; /* number of iterations performed */ + gsl_multifit_nlinear_parameters params; + void *state; +} gsl_multifit_nlinear_workspace; + +gsl_multifit_nlinear_workspace * +gsl_multifit_nlinear_alloc (const gsl_multifit_nlinear_type * T, + const gsl_multifit_nlinear_parameters * params, + size_t n, size_t p); + +void gsl_multifit_nlinear_free (gsl_multifit_nlinear_workspace * w); + +gsl_multifit_nlinear_parameters gsl_multifit_nlinear_default_parameters(void); + +int +gsl_multifit_nlinear_init (const gsl_vector * x, + gsl_multifit_nlinear_fdf * fdf, + gsl_multifit_nlinear_workspace * w); + +int gsl_multifit_nlinear_winit (const gsl_vector * x, + const gsl_vector * wts, + gsl_multifit_nlinear_fdf * fdf, + gsl_multifit_nlinear_workspace * w); + +int +gsl_multifit_nlinear_iterate (gsl_multifit_nlinear_workspace * w); + +double +gsl_multifit_nlinear_avratio (const gsl_multifit_nlinear_workspace * w); + +int +gsl_multifit_nlinear_driver (const size_t maxiter, + const double xtol, + const double gtol, + const double ftol, + void (*callback)(const size_t iter, void *params, + const gsl_multifit_nlinear_workspace *w), + void *callback_params, + int *info, + gsl_multifit_nlinear_workspace * w); + +gsl_matrix * +gsl_multifit_nlinear_jac (const gsl_multifit_nlinear_workspace * w); + +const char * +gsl_multifit_nlinear_name (const gsl_multifit_nlinear_workspace * w); + +gsl_vector * +gsl_multifit_nlinear_position (const gsl_multifit_nlinear_workspace * w); + +gsl_vector * +gsl_multifit_nlinear_residual (const gsl_multifit_nlinear_workspace * w); + +size_t +gsl_multifit_nlinear_niter (const gsl_multifit_nlinear_workspace * w); + +int +gsl_multifit_nlinear_rcond (double *rcond, const gsl_multifit_nlinear_workspace * w); + +const char * +gsl_multifit_nlinear_trs_name (const gsl_multifit_nlinear_workspace * w); + +int gsl_multifit_nlinear_eval_f(gsl_multifit_nlinear_fdf *fdf, + const gsl_vector *x, + const gsl_vector *swts, + gsl_vector *y); + +int gsl_multifit_nlinear_eval_df(const gsl_vector *x, + const gsl_vector *f, + const gsl_vector *swts, + const double h, + const gsl_multifit_nlinear_fdtype fdtype, + gsl_multifit_nlinear_fdf *fdf, + gsl_matrix *df, gsl_vector *work); + +int +gsl_multifit_nlinear_eval_fvv(const double h, + const gsl_vector *x, + const gsl_vector *v, + const gsl_vector *f, + const gsl_matrix *J, + const gsl_vector *swts, + gsl_multifit_nlinear_fdf *fdf, + gsl_vector *yvv, gsl_vector *work); + +/* covar.c */ +int +gsl_multifit_nlinear_covar (const gsl_matrix * J, const double epsrel, + gsl_matrix * covar); + +/* convergence.c */ +int +gsl_multifit_nlinear_test (const double xtol, const double gtol, + const double ftol, int *info, + const gsl_multifit_nlinear_workspace * w); + +/* fdjac.c */ +int +gsl_multifit_nlinear_df(const double h, const gsl_multifit_nlinear_fdtype fdtype, + const gsl_vector *x, const gsl_vector *wts, + gsl_multifit_nlinear_fdf *fdf, + const gsl_vector *f, gsl_matrix *J, gsl_vector *work); + +/* fdfvv.c */ +int +gsl_multifit_nlinear_fdfvv(const double h, const gsl_vector *x, const gsl_vector *v, + const gsl_vector *f, const gsl_matrix *J, + const gsl_vector *swts, gsl_multifit_nlinear_fdf *fdf, + gsl_vector *fvv, gsl_vector *work); + +/* top-level algorithms */ +GSL_VAR const gsl_multifit_nlinear_type * gsl_multifit_nlinear_trust; + +/* trust region subproblem methods */ +GSL_VAR const gsl_multifit_nlinear_trs * gsl_multifit_nlinear_trs_lm; +GSL_VAR const gsl_multifit_nlinear_trs * gsl_multifit_nlinear_trs_lmaccel; +GSL_VAR const gsl_multifit_nlinear_trs * gsl_multifit_nlinear_trs_dogleg; +GSL_VAR const gsl_multifit_nlinear_trs * gsl_multifit_nlinear_trs_ddogleg; +GSL_VAR const gsl_multifit_nlinear_trs * gsl_multifit_nlinear_trs_subspace2D; + +/* scaling matrix strategies */ +GSL_VAR const gsl_multifit_nlinear_scale * gsl_multifit_nlinear_scale_levenberg; +GSL_VAR const gsl_multifit_nlinear_scale * gsl_multifit_nlinear_scale_marquardt; +GSL_VAR const gsl_multifit_nlinear_scale * gsl_multifit_nlinear_scale_more; + +/* linear solvers */ +GSL_VAR const gsl_multifit_nlinear_solver * gsl_multifit_nlinear_solver_cholesky; +GSL_VAR const gsl_multifit_nlinear_solver * gsl_multifit_nlinear_solver_mcholesky; +GSL_VAR const gsl_multifit_nlinear_solver * gsl_multifit_nlinear_solver_qr; +GSL_VAR const gsl_multifit_nlinear_solver * gsl_multifit_nlinear_solver_svd; + +__END_DECLS + +#endif /* __GSL_MULTIFIT_NLINEAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge.h new file mode 100644 index 0000000..46728b5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge.h @@ -0,0 +1,147 @@ +/* gsl_multilarge.h + * + * Copyright (C) 2015 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTILARGE_H__ +#define __GSL_MULTILARGE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* iteration solver type */ +typedef struct +{ + const char *name; + void * (*alloc) (const size_t p); + int (*reset) (void *); + int (*accumulate) (gsl_matrix * X, gsl_vector * y, + void *); + int (*solve) (const double lambda, gsl_vector * c, + double * rnorm, double * snorm, void *); + int (*rcond) (double * rcond, void *); + int (*lcurve) (gsl_vector * reg_param, gsl_vector * rho, + gsl_vector * eta, void *); + const gsl_matrix * (*matrix_ptr) (const void *); + const gsl_vector * (*rhs_ptr) (const void *); + void (*free) (void *); +} gsl_multilarge_linear_type; + +typedef struct +{ + const gsl_multilarge_linear_type * type; + void * state; + size_t p; +} gsl_multilarge_linear_workspace; + +/* available types */ +GSL_VAR const gsl_multilarge_linear_type * gsl_multilarge_linear_normal; +GSL_VAR const gsl_multilarge_linear_type * gsl_multilarge_linear_tsqr; + +/* + * Prototypes + */ +gsl_multilarge_linear_workspace * +gsl_multilarge_linear_alloc(const gsl_multilarge_linear_type * T, + const size_t p); + +void gsl_multilarge_linear_free(gsl_multilarge_linear_workspace * w); + +const char *gsl_multilarge_linear_name(const gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_reset(gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_accumulate(gsl_matrix * X, + gsl_vector * y, + gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_solve(const double lambda, gsl_vector * c, + double * rnorm, double * snorm, + gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_rcond(double *rcond, gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_lcurve(gsl_vector * reg_param, gsl_vector * rho, + gsl_vector * eta, + gsl_multilarge_linear_workspace * w); + +int gsl_multilarge_linear_wstdform1 (const gsl_vector * L, + const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multilarge_linear_workspace * work); + +int gsl_multilarge_linear_stdform1 (const gsl_vector * L, + const gsl_matrix * X, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multilarge_linear_workspace * work); + +int gsl_multilarge_linear_L_decomp (gsl_matrix * L, gsl_vector * tau); + +int gsl_multilarge_linear_wstdform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * w, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multilarge_linear_workspace * work); + +int gsl_multilarge_linear_stdform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_matrix * X, + const gsl_vector * y, + gsl_matrix * Xs, + gsl_vector * ys, + gsl_multilarge_linear_workspace * work); + +int gsl_multilarge_linear_genform1 (const gsl_vector * L, + const gsl_vector * cs, + gsl_vector * c, + gsl_multilarge_linear_workspace * work); + +int gsl_multilarge_linear_genform2 (const gsl_matrix * LQR, + const gsl_vector * Ltau, + const gsl_vector * cs, + gsl_vector * c, + gsl_multilarge_linear_workspace * work); + +const gsl_matrix * gsl_multilarge_linear_matrix_ptr (const gsl_multilarge_linear_workspace * work); + +const gsl_vector * gsl_multilarge_linear_rhs_ptr (const gsl_multilarge_linear_workspace * work); + +__END_DECLS + +#endif /* __GSL_MULTILARGE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge_nlinear.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge_nlinear.h new file mode 100644 index 0000000..e27c68b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multilarge_nlinear.h @@ -0,0 +1,314 @@ +/* multilarge_nlinear/gsl_multilarge_nlinear.h + * + * Copyright (C) 2015, 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTILARGE_NLINEAR_H__ +#define __GSL_MULTILARGE_NLINEAR_H__ + +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum +{ + GSL_MULTILARGE_NLINEAR_FWDIFF, + GSL_MULTILARGE_NLINEAR_CTRDIFF +} gsl_multilarge_nlinear_fdtype; + +/* Definition of vector-valued functions and gradient with parameters + based on gsl_vector */ + +typedef struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + int (* df) (CBLAS_TRANSPOSE_t TransJ, const gsl_vector * x, + const gsl_vector * u, void * params, gsl_vector * v, + gsl_matrix * JTJ); + int (* fvv) (const gsl_vector * x, const gsl_vector * v, void * params, + gsl_vector * fvv); + size_t n; /* number of functions */ + size_t p; /* number of independent variables */ + void * params; /* user parameters */ + size_t nevalf; /* number of function evaluations */ + size_t nevaldfu; /* number of Jacobian matrix-vector evaluations */ + size_t nevaldf2; /* number of Jacobian J^T J evaluations */ + size_t nevalfvv; /* number of fvv evaluations */ +} gsl_multilarge_nlinear_fdf; + +/* trust region subproblem method */ +typedef struct +{ + const char *name; + void * (*alloc) (const void * params, const size_t n, const size_t p); + int (*init) (const void * vtrust_state, void * vstate); + int (*preloop) (const void * vtrust_state, void * vstate); + int (*step) (const void * vtrust_state, const double delta, + gsl_vector * dx, void * vstate); + int (*preduction) (const void * vtrust_state, const gsl_vector * dx, + double * pred, void * vstate); + void (*free) (void * vstate); +} gsl_multilarge_nlinear_trs; + +/* scaling matrix specification */ +typedef struct +{ + const char *name; + int (*init) (const gsl_matrix * JTJ, gsl_vector * diag); + int (*update) (const gsl_matrix * JTJ, gsl_vector * diag); +} gsl_multilarge_nlinear_scale; + +/* + * linear least squares solvers - there are three steps to + * solving a least squares problem using a direct method: + * + * 1. init: called once per iteration when a new Jacobian matrix + * is required; form normal equations matrix J^T J + * 2. presolve: called each time a new LM parameter value mu is available; + * used for cholesky method in order to factor + * the (J^T J + mu D^T D) matrix + * 3. solve: solve the least square system for a given rhs + */ +typedef struct +{ + const char *name; + void * (*alloc) (const size_t n, const size_t p); + int (*init) (const void * vtrust_state, void * vstate); + int (*presolve) (const double mu, const void * vtrust_state, void * vstate); + int (*solve) (const gsl_vector * g, gsl_vector * x, + const void * vtrust_state, void * vstate); + int (*rcond) (double * rcond, const gsl_matrix * JTJ, void * vstate); + int (*covar) (const gsl_matrix * JTJ, gsl_matrix * covar, void * vstate); + void (*free) (void * vstate); +} gsl_multilarge_nlinear_solver; + +/* tunable parameters */ +typedef struct +{ + const gsl_multilarge_nlinear_trs *trs; /* trust region subproblem method */ + const gsl_multilarge_nlinear_scale *scale; /* scaling method */ + const gsl_multilarge_nlinear_solver *solver; /* solver method */ + gsl_multilarge_nlinear_fdtype fdtype; /* finite difference method */ + double factor_up; /* factor for increasing trust radius */ + double factor_down; /* factor for decreasing trust radius */ + double avmax; /* max allowed |a|/|v| */ + double h_df; /* step size for finite difference Jacobian */ + double h_fvv; /* step size for finite difference fvv */ + size_t max_iter; /* maximum iterations for trs method */ + double tol; /* tolerance for solving trs */ +} gsl_multilarge_nlinear_parameters; + +typedef struct +{ + const char *name; + void * (*alloc) (const gsl_multilarge_nlinear_parameters * params, + const size_t n, const size_t p); + int (*init) (void * state, const gsl_vector * wts, + gsl_multilarge_nlinear_fdf * fdf, const gsl_vector * x, + gsl_vector * f, gsl_vector * g, gsl_matrix * JTJ); + int (*iterate) (void * state, const gsl_vector * wts, + gsl_multilarge_nlinear_fdf * fdf, gsl_vector * x, + gsl_vector * f, gsl_vector * g, gsl_matrix * JTJ, + gsl_vector * dx); + int (*rcond) (double * rcond, const gsl_matrix * JTJ, void * state); + int (*covar) (const gsl_matrix * JTJ, gsl_matrix * covar, void * state); + double (*avratio) (void * state); + void (*free) (void * state); +} gsl_multilarge_nlinear_type; + +/* current state passed to low-level trust region algorithms */ +typedef struct +{ + const gsl_vector * x; /* parameter values x */ + const gsl_vector * f; /* residual vector f(x) */ + const gsl_vector * g; /* gradient J^T f */ + const gsl_matrix * JTJ; /* matrix J^T J */ + const gsl_vector * diag; /* scaling matrix D */ + const gsl_vector * sqrt_wts; /* sqrt(diag(W)) or NULL for unweighted */ + const double *mu; /* LM parameter */ + const gsl_multilarge_nlinear_parameters * params; + void *solver_state; /* workspace for direct least squares solver */ + gsl_multilarge_nlinear_fdf * fdf; + double *avratio; /* |a| / |v| */ +} gsl_multilarge_nlinear_trust_state; + +typedef struct +{ + const gsl_multilarge_nlinear_type * type; + gsl_multilarge_nlinear_fdf * fdf ; + gsl_vector * x; /* parameter values x */ + gsl_vector * f; /* residual vector f(x) */ + gsl_vector * dx; /* step dx */ + gsl_vector * g; /* gradient J^T f */ + gsl_matrix * JTJ; /* matrix J^T J */ + gsl_vector * sqrt_wts_work; /* sqrt(W) */ + gsl_vector * sqrt_wts; /* ptr to sqrt_wts_work, or NULL if not using weights */ + size_t n; /* number of residuals */ + size_t p; /* number of parameters */ + size_t niter; /* number of iterations performed */ + gsl_multilarge_nlinear_parameters params; + void *state; +} gsl_multilarge_nlinear_workspace; + +gsl_multilarge_nlinear_workspace * +gsl_multilarge_nlinear_alloc (const gsl_multilarge_nlinear_type * T, + const gsl_multilarge_nlinear_parameters * params, + size_t n, size_t p); + +void gsl_multilarge_nlinear_free (gsl_multilarge_nlinear_workspace * w); + +gsl_multilarge_nlinear_parameters gsl_multilarge_nlinear_default_parameters(void); + +int +gsl_multilarge_nlinear_init (const gsl_vector * x, + gsl_multilarge_nlinear_fdf * fdf, + gsl_multilarge_nlinear_workspace * w); + +int gsl_multilarge_nlinear_winit (const gsl_vector * x, + const gsl_vector * wts, + gsl_multilarge_nlinear_fdf * fdf, + gsl_multilarge_nlinear_workspace * w); + +int +gsl_multilarge_nlinear_iterate (gsl_multilarge_nlinear_workspace * w); + +double +gsl_multilarge_nlinear_avratio (const gsl_multilarge_nlinear_workspace * w); + +int +gsl_multilarge_nlinear_rcond (double * rcond, const gsl_multilarge_nlinear_workspace * w); + +int +gsl_multilarge_nlinear_covar (gsl_matrix * covar, gsl_multilarge_nlinear_workspace * w); + +int +gsl_multilarge_nlinear_driver (const size_t maxiter, + const double xtol, + const double gtol, + const double ftol, + void (*callback)(const size_t iter, void *params, + const gsl_multilarge_nlinear_workspace *w), + void *callback_params, + int *info, + gsl_multilarge_nlinear_workspace * w); + +const char * +gsl_multilarge_nlinear_name (const gsl_multilarge_nlinear_workspace * w); + +gsl_vector * +gsl_multilarge_nlinear_position (const gsl_multilarge_nlinear_workspace * w); + +gsl_vector * +gsl_multilarge_nlinear_residual (const gsl_multilarge_nlinear_workspace * w); + +gsl_vector * +gsl_multilarge_nlinear_step (const gsl_multilarge_nlinear_workspace * w); + +size_t +gsl_multilarge_nlinear_niter (const gsl_multilarge_nlinear_workspace * w); + +const char * +gsl_multilarge_nlinear_trs_name (const gsl_multilarge_nlinear_workspace * w); + +int gsl_multilarge_nlinear_eval_f(gsl_multilarge_nlinear_fdf *fdf, + const gsl_vector *x, + const gsl_vector *swts, + gsl_vector *y); + +int +gsl_multilarge_nlinear_eval_df(const CBLAS_TRANSPOSE_t TransJ, + const gsl_vector *x, + const gsl_vector *f, + const gsl_vector *u, + const gsl_vector *swts, + const double h, + const gsl_multilarge_nlinear_fdtype fdtype, + gsl_multilarge_nlinear_fdf *fdf, + gsl_vector *v, + gsl_matrix *JTJ, + gsl_vector *work); + +int +gsl_multilarge_nlinear_eval_fvv(const double h, + const gsl_vector *x, + const gsl_vector *v, + const gsl_vector *f, + const gsl_vector *swts, + gsl_multilarge_nlinear_fdf *fdf, + gsl_vector *yvv, + gsl_vector *work); + +/* convergence.c */ +int +gsl_multilarge_nlinear_test (const double xtol, const double gtol, + const double ftol, int *info, + const gsl_multilarge_nlinear_workspace * w); + +/* fdjac.c */ +int +gsl_multilarge_nlinear_df(const double h, const gsl_multilarge_nlinear_fdtype fdtype, + const gsl_vector *x, const gsl_vector *wts, + gsl_multilarge_nlinear_fdf *fdf, + const gsl_vector *f, gsl_matrix *J, gsl_vector *work); + +/* fdfvv.c */ +int +gsl_multilarge_nlinear_fdfvv(const double h, const gsl_vector *x, const gsl_vector *v, + const gsl_vector *f, const gsl_matrix *J, + const gsl_vector *swts, gsl_multilarge_nlinear_fdf *fdf, + gsl_vector *fvv, gsl_vector *work); + +/* top-level algorithms */ +GSL_VAR const gsl_multilarge_nlinear_type * gsl_multilarge_nlinear_trust; + +/* trust region subproblem methods */ +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_lm; +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_lmaccel; +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_dogleg; +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_ddogleg; +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_subspace2D; +GSL_VAR const gsl_multilarge_nlinear_trs * gsl_multilarge_nlinear_trs_cgst; + +/* scaling matrix strategies */ +GSL_VAR const gsl_multilarge_nlinear_scale * gsl_multilarge_nlinear_scale_levenberg; +GSL_VAR const gsl_multilarge_nlinear_scale * gsl_multilarge_nlinear_scale_marquardt; +GSL_VAR const gsl_multilarge_nlinear_scale * gsl_multilarge_nlinear_scale_more; + +/* linear solvers */ +GSL_VAR const gsl_multilarge_nlinear_solver * gsl_multilarge_nlinear_solver_cholesky; +GSL_VAR const gsl_multilarge_nlinear_solver * gsl_multilarge_nlinear_solver_mcholesky; +GSL_VAR const gsl_multilarge_nlinear_solver * gsl_multilarge_nlinear_solver_none; + +__END_DECLS + +#endif /* __GSL_MULTILARGE_NLINEAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multimin.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multimin.h new file mode 100644 index 0000000..2870227 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multimin.h @@ -0,0 +1,226 @@ +/* multimin/gsl_multimin.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Modified by Tuomo Keskitalo to include fminimizer and + Nelder Mead related lines */ + +#ifndef __GSL_MULTIMIN_H__ +#define __GSL_MULTIMIN_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Definition of an arbitrary real-valued function with gsl_vector input and */ +/* parameters */ +struct gsl_multimin_function_struct +{ + double (* f) (const gsl_vector * x, void * params); + size_t n; + void * params; +}; + +typedef struct gsl_multimin_function_struct gsl_multimin_function; + +#define GSL_MULTIMIN_FN_EVAL(F,x) (*((F)->f))(x,(F)->params) + +/* Definition of an arbitrary differentiable real-valued function */ +/* with gsl_vector input and parameters */ +struct gsl_multimin_function_fdf_struct +{ + double (* f) (const gsl_vector * x, void * params); + void (* df) (const gsl_vector * x, void * params,gsl_vector * df); + void (* fdf) (const gsl_vector * x, void * params,double *f,gsl_vector * df); + size_t n; + void * params; +}; + +typedef struct gsl_multimin_function_fdf_struct gsl_multimin_function_fdf; + +#define GSL_MULTIMIN_FN_EVAL_F(F,x) (*((F)->f))(x,(F)->params) +#define GSL_MULTIMIN_FN_EVAL_DF(F,x,g) (*((F)->df))(x,(F)->params,(g)) +#define GSL_MULTIMIN_FN_EVAL_F_DF(F,x,y,g) (*((F)->fdf))(x,(F)->params,(y),(g)) + +int gsl_multimin_diff (const gsl_multimin_function * f, + const gsl_vector * x, gsl_vector * g); + +/* minimization of non-differentiable functions */ + +typedef struct +{ + const char *name; + size_t size; + int (*alloc) (void *state, size_t n); + int (*set) (void *state, gsl_multimin_function * f, + const gsl_vector * x, + double * size, + const gsl_vector * step_size); + int (*iterate) (void *state, gsl_multimin_function * f, + gsl_vector * x, + double * size, + double * fval); + void (*free) (void *state); +} +gsl_multimin_fminimizer_type; + +typedef struct +{ + /* multi dimensional part */ + const gsl_multimin_fminimizer_type *type; + gsl_multimin_function *f; + + double fval; + gsl_vector * x; + + double size; + + void *state; +} +gsl_multimin_fminimizer; + +gsl_multimin_fminimizer * +gsl_multimin_fminimizer_alloc(const gsl_multimin_fminimizer_type *T, + size_t n); + +int +gsl_multimin_fminimizer_set (gsl_multimin_fminimizer * s, + gsl_multimin_function * f, + const gsl_vector * x, + const gsl_vector * step_size); + +void +gsl_multimin_fminimizer_free(gsl_multimin_fminimizer *s); + +const char * +gsl_multimin_fminimizer_name (const gsl_multimin_fminimizer * s); + +int +gsl_multimin_fminimizer_iterate(gsl_multimin_fminimizer *s); + +gsl_vector * +gsl_multimin_fminimizer_x (const gsl_multimin_fminimizer * s); + +double +gsl_multimin_fminimizer_minimum (const gsl_multimin_fminimizer * s); + +double +gsl_multimin_fminimizer_size (const gsl_multimin_fminimizer * s); + +/* Convergence test functions */ + +int +gsl_multimin_test_gradient(const gsl_vector * g, double epsabs); + +int +gsl_multimin_test_size(const double size, double epsabs); + +/* minimisation of differentiable functions */ + +typedef struct +{ + const char *name; + size_t size; + int (*alloc) (void *state, size_t n); + int (*set) (void *state, gsl_multimin_function_fdf * fdf, + const gsl_vector * x, double * f, + gsl_vector * gradient, double step_size, double tol); + int (*iterate) (void *state,gsl_multimin_function_fdf * fdf, + gsl_vector * x, double * f, + gsl_vector * gradient, gsl_vector * dx); + int (*restart) (void *state); + void (*free) (void *state); +} +gsl_multimin_fdfminimizer_type; + +typedef struct +{ + /* multi dimensional part */ + const gsl_multimin_fdfminimizer_type *type; + gsl_multimin_function_fdf *fdf; + + double f; + gsl_vector * x; + gsl_vector * gradient; + gsl_vector * dx; + + void *state; +} +gsl_multimin_fdfminimizer; + +gsl_multimin_fdfminimizer * +gsl_multimin_fdfminimizer_alloc(const gsl_multimin_fdfminimizer_type *T, + size_t n); + +int +gsl_multimin_fdfminimizer_set (gsl_multimin_fdfminimizer * s, + gsl_multimin_function_fdf *fdf, + const gsl_vector * x, + double step_size, double tol); + +void +gsl_multimin_fdfminimizer_free(gsl_multimin_fdfminimizer *s); + +const char * +gsl_multimin_fdfminimizer_name (const gsl_multimin_fdfminimizer * s); + +int +gsl_multimin_fdfminimizer_iterate(gsl_multimin_fdfminimizer *s); + +int +gsl_multimin_fdfminimizer_restart(gsl_multimin_fdfminimizer *s); + +gsl_vector * +gsl_multimin_fdfminimizer_x (const gsl_multimin_fdfminimizer * s); + +gsl_vector * +gsl_multimin_fdfminimizer_dx (const gsl_multimin_fdfminimizer * s); + +gsl_vector * +gsl_multimin_fdfminimizer_gradient (const gsl_multimin_fdfminimizer * s); + +double +gsl_multimin_fdfminimizer_minimum (const gsl_multimin_fdfminimizer * s); + +GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_steepest_descent; +GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_conjugate_pr; +GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_conjugate_fr; +GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_vector_bfgs; +GSL_VAR const gsl_multimin_fdfminimizer_type *gsl_multimin_fdfminimizer_vector_bfgs2; +GSL_VAR const gsl_multimin_fminimizer_type *gsl_multimin_fminimizer_nmsimplex; +GSL_VAR const gsl_multimin_fminimizer_type *gsl_multimin_fminimizer_nmsimplex2; +GSL_VAR const gsl_multimin_fminimizer_type *gsl_multimin_fminimizer_nmsimplex2rand; + +__END_DECLS + +#endif /* __GSL_MULTIMIN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multiroots.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multiroots.h new file mode 100644 index 0000000..7f66154 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multiroots.h @@ -0,0 +1,177 @@ +/* multiroots/gsl_multiroots.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTIROOTS_H__ +#define __GSL_MULTIROOTS_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Definition of vector-valued functions with parameters based on gsl_vector */ + +struct gsl_multiroot_function_struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + size_t n; + void * params; +}; + +typedef struct gsl_multiroot_function_struct gsl_multiroot_function ; + +#define GSL_MULTIROOT_FN_EVAL(F,x,y) (*((F)->f))(x,(F)->params,(y)) + +int gsl_multiroot_fdjacobian (gsl_multiroot_function * F, + const gsl_vector * x, const gsl_vector * f, + double epsrel, gsl_matrix * jacobian); + + +typedef struct + { + const char *name; + size_t size; + int (*alloc) (void *state, size_t n); + int (*set) (void *state, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); + int (*iterate) (void *state, gsl_multiroot_function * function, gsl_vector * x, gsl_vector * f, gsl_vector * dx); + void (*free) (void *state); + } +gsl_multiroot_fsolver_type; + +typedef struct + { + const gsl_multiroot_fsolver_type * type; + gsl_multiroot_function * function ; + gsl_vector * x ; + gsl_vector * f ; + gsl_vector * dx ; + void *state; + } +gsl_multiroot_fsolver; + +gsl_multiroot_fsolver * +gsl_multiroot_fsolver_alloc (const gsl_multiroot_fsolver_type * T, + size_t n); + +void gsl_multiroot_fsolver_free (gsl_multiroot_fsolver * s); + +int gsl_multiroot_fsolver_set (gsl_multiroot_fsolver * s, + gsl_multiroot_function * f, + const gsl_vector * x); + +int gsl_multiroot_fsolver_iterate (gsl_multiroot_fsolver * s); + +const char * gsl_multiroot_fsolver_name (const gsl_multiroot_fsolver * s); +gsl_vector * gsl_multiroot_fsolver_root (const gsl_multiroot_fsolver * s); +gsl_vector * gsl_multiroot_fsolver_dx (const gsl_multiroot_fsolver * s); +gsl_vector * gsl_multiroot_fsolver_f (const gsl_multiroot_fsolver * s); + +/* Definition of vector-valued functions and gradient with parameters + based on gsl_vector */ + +struct gsl_multiroot_function_fdf_struct +{ + int (* f) (const gsl_vector * x, void * params, gsl_vector * f); + int (* df) (const gsl_vector * x, void * params, gsl_matrix * df); + int (* fdf) (const gsl_vector * x, void * params, gsl_vector * f, gsl_matrix *df); + size_t n; + void * params; +}; + +typedef struct gsl_multiroot_function_fdf_struct gsl_multiroot_function_fdf ; + +#define GSL_MULTIROOT_FN_EVAL_F(F,x,y) ((*((F)->f))(x,(F)->params,(y))) +#define GSL_MULTIROOT_FN_EVAL_DF(F,x,dy) ((*((F)->df))(x,(F)->params,(dy))) +#define GSL_MULTIROOT_FN_EVAL_F_DF(F,x,y,dy) ((*((F)->fdf))(x,(F)->params,(y),(dy))) + +typedef struct + { + const char *name; + size_t size; + int (*alloc) (void *state, size_t n); + int (*set) (void *state, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); + int (*iterate) (void *state, gsl_multiroot_function_fdf * fdf, gsl_vector * x, gsl_vector * f, gsl_matrix * J, gsl_vector * dx); + void (*free) (void *state); + } +gsl_multiroot_fdfsolver_type; + +typedef struct + { + const gsl_multiroot_fdfsolver_type * type; + gsl_multiroot_function_fdf * fdf ; + gsl_vector * x; + gsl_vector * f; + gsl_matrix * J; + gsl_vector * dx; + void *state; + } +gsl_multiroot_fdfsolver; + +gsl_multiroot_fdfsolver * +gsl_multiroot_fdfsolver_alloc (const gsl_multiroot_fdfsolver_type * T, + size_t n); + +int +gsl_multiroot_fdfsolver_set (gsl_multiroot_fdfsolver * s, + gsl_multiroot_function_fdf * fdf, + const gsl_vector * x); + +int +gsl_multiroot_fdfsolver_iterate (gsl_multiroot_fdfsolver * s); + +void +gsl_multiroot_fdfsolver_free (gsl_multiroot_fdfsolver * s); + +const char * gsl_multiroot_fdfsolver_name (const gsl_multiroot_fdfsolver * s); +gsl_vector * gsl_multiroot_fdfsolver_root (const gsl_multiroot_fdfsolver * s); +gsl_vector * gsl_multiroot_fdfsolver_dx (const gsl_multiroot_fdfsolver * s); +gsl_vector * gsl_multiroot_fdfsolver_f (const gsl_multiroot_fdfsolver * s); + +int gsl_multiroot_test_delta (const gsl_vector * dx, const gsl_vector * x, + double epsabs, double epsrel); + +int gsl_multiroot_test_residual (const gsl_vector * f, double epsabs); + +GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_dnewton; +GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_broyden; +GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_hybrid; +GSL_VAR const gsl_multiroot_fsolver_type * gsl_multiroot_fsolver_hybrids; + +GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_newton; +GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_gnewton; +GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_hybridj; +GSL_VAR const gsl_multiroot_fdfsolver_type * gsl_multiroot_fdfsolver_hybridsj; + + +__END_DECLS + +#endif /* __GSL_MULTIROOTS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_multiset.h b/ChaosDataPlayer/GSL/include/gsl/gsl_multiset.h new file mode 100644 index 0000000..1ba5d6c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_multiset.h @@ -0,0 +1,93 @@ +/* multiset/gsl_multiset.h + * based on combination/gsl_combination.h by Szymon Jaroszewicz + * based on permutation/gsl_permutation.h by Brian Gough + * + * Copyright (C) 2009 Rhys Ulerich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_MULTISET_H__ +#define __GSL_MULTISET_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_multiset_struct +{ + size_t n; + size_t k; + size_t *data; +}; + +typedef struct gsl_multiset_struct gsl_multiset; + +gsl_multiset *gsl_multiset_alloc (const size_t n, const size_t k); +gsl_multiset *gsl_multiset_calloc (const size_t n, const size_t k); +void gsl_multiset_init_first (gsl_multiset * c); +void gsl_multiset_init_last (gsl_multiset * c); +void gsl_multiset_free (gsl_multiset * c); +int gsl_multiset_memcpy (gsl_multiset * dest, const gsl_multiset * src); + +int gsl_multiset_fread (FILE * stream, gsl_multiset * c); +int gsl_multiset_fwrite (FILE * stream, const gsl_multiset * c); +int gsl_multiset_fscanf (FILE * stream, gsl_multiset * c); +int gsl_multiset_fprintf (FILE * stream, const gsl_multiset * c, const char *format); + +size_t gsl_multiset_n (const gsl_multiset * c); +size_t gsl_multiset_k (const gsl_multiset * c); +size_t * gsl_multiset_data (const gsl_multiset * c); + +int gsl_multiset_valid (gsl_multiset * c); +int gsl_multiset_next (gsl_multiset * c); +int gsl_multiset_prev (gsl_multiset * c); + +INLINE_DECL size_t gsl_multiset_get (const gsl_multiset * c, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +size_t +gsl_multiset_get (const gsl_multiset * c, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= c->k)) /* size_t is unsigned, can't be negative */ + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return c->data[i]; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_MULTISET_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_nan.h b/ChaosDataPlayer/GSL/include/gsl/gsl_nan.h new file mode 100644 index 0000000..5cb52ef --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_nan.h @@ -0,0 +1,45 @@ +/* gsl_nan.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_NAN_H__ +#define __GSL_NAN_H__ + +#ifdef INFINITY +# define GSL_POSINF INFINITY +# define GSL_NEGINF (-INFINITY) +#elif defined(HUGE_VAL) +# define GSL_POSINF HUGE_VAL +# define GSL_NEGINF (-HUGE_VAL) +#else +# define GSL_POSINF (gsl_posinf()) +# define GSL_NEGINF (gsl_neginf()) +#endif + +#ifdef NAN +# define GSL_NAN NAN +#elif defined(INFINITY) +# define GSL_NAN (INFINITY/INFINITY) +#else +# define GSL_NAN (gsl_nan()) +#endif + +#define GSL_POSZERO (+0.0) +#define GSL_NEGZERO (-0.0) + +#endif /* __GSL_NAN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_ntuple.h b/ChaosDataPlayer/GSL/include/gsl/gsl_ntuple.h new file mode 100644 index 0000000..90d8a26 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_ntuple.h @@ -0,0 +1,82 @@ +/* histogram/ntuple.h + * + * Copyright (C) 2000 Simone Piccardi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* Jan/2001 Modified by Brian Gough. Minor changes for GSL */ + +#ifndef __GSL_NTUPLE_H__ +#define __GSL_NTUPLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct { + FILE * file; + void * ntuple_data; + size_t size; +} gsl_ntuple; + +typedef struct { + int (* function) (void * ntuple_data, void * params); + void * params; +} gsl_ntuple_select_fn; + +typedef struct { + double (* function) (void * ntuple_data, void * params); + void * params; +} gsl_ntuple_value_fn; + +gsl_ntuple * +gsl_ntuple_open (char * filename, void * ntuple_data, size_t size); + +gsl_ntuple * +gsl_ntuple_create (char * filename, void * ntuple_data, size_t size); + +int gsl_ntuple_write (gsl_ntuple * ntuple); +int gsl_ntuple_read (gsl_ntuple * ntuple); + +int gsl_ntuple_bookdata (gsl_ntuple * ntuple); /* synonym for write */ + +int gsl_ntuple_project (gsl_histogram * h, gsl_ntuple * ntuple, + gsl_ntuple_value_fn *value_func, + gsl_ntuple_select_fn *select_func); + +int gsl_ntuple_close (gsl_ntuple * ntuple); + +__END_DECLS + +#endif /* __GSL_NTUPLE_H__ */ + + + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv.h b/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv.h new file mode 100644 index 0000000..d70f150 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv.h @@ -0,0 +1,230 @@ +/* ode-initval/gsl_odeiv.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman + */ +#ifndef __GSL_ODEIV_H__ +#define __GSL_ODEIV_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Description of a system of ODEs. + * + * y' = f(t,y) = dydt(t, y) + * + * The system is specified by giving the right-hand-side + * of the equation and possibly a jacobian function. + * + * Some methods require the jacobian function, which calculates + * the matrix dfdy and the vector dfdt. The matrix dfdy conforms + * to the GSL standard, being a continuous range of floating point + * values, in row-order. + * + * As with GSL function objects, user-supplied parameter + * data is also present. + */ + +typedef struct +{ + int (* function) (double t, const double y[], double dydt[], void * params); + int (* jacobian) (double t, const double y[], double * dfdy, double dfdt[], void * params); + size_t dimension; + void * params; +} +gsl_odeiv_system; + +#define GSL_ODEIV_FN_EVAL(S,t,y,f) (*((S)->function))(t,y,f,(S)->params) +#define GSL_ODEIV_JA_EVAL(S,t,y,dfdy,dfdt) (*((S)->jacobian))(t,y,dfdy,dfdt,(S)->params) + + +/* General stepper object. + * + * Opaque object for stepping an ODE system from t to t+h. + * In general the object has some state which facilitates + * iterating the stepping operation. + */ + +typedef struct +{ + const char * name; + int can_use_dydt_in; + int gives_exact_dydt_out; + void * (*alloc) (size_t dim); + int (*apply) (void * state, size_t dim, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt); + int (*reset) (void * state, size_t dim); + unsigned int (*order) (void * state); + void (*free) (void * state); +} +gsl_odeiv_step_type; + +typedef struct { + const gsl_odeiv_step_type * type; + size_t dimension; + void * state; +} +gsl_odeiv_step; + + +/* Available stepper types. + * + * rk2 : embedded 2nd(3rd) Runge-Kutta + * rk4 : 4th order (classical) Runge-Kutta + * rkck : embedded 4th(5th) Runge-Kutta, Cash-Karp + * rk8pd : embedded 8th(9th) Runge-Kutta, Prince-Dormand + * rk2imp : implicit 2nd order Runge-Kutta at Gaussian points + * rk4imp : implicit 4th order Runge-Kutta at Gaussian points + * gear1 : M=1 implicit Gear method + * gear2 : M=2 implicit Gear method + */ + +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk4; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rkf45; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rkck; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk8pd; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2imp; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk2simp; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_rk4imp; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_bsimp; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_gear1; +GSL_VAR const gsl_odeiv_step_type *gsl_odeiv_step_gear2; + + +/* Constructor for specialized stepper objects. + */ +gsl_odeiv_step * gsl_odeiv_step_alloc(const gsl_odeiv_step_type * T, size_t dim); +int gsl_odeiv_step_reset(gsl_odeiv_step * s); +void gsl_odeiv_step_free(gsl_odeiv_step * s); + +/* General stepper object methods. + */ +const char * gsl_odeiv_step_name(const gsl_odeiv_step * s); +unsigned int gsl_odeiv_step_order(const gsl_odeiv_step * s); + +int gsl_odeiv_step_apply(gsl_odeiv_step * s, double t, double h, double y[], double yerr[], const double dydt_in[], double dydt_out[], const gsl_odeiv_system * dydt); + +/* General step size control object. + * + * The hadjust() method controls the adjustment of + * step size given the result of a step and the error. + * Valid hadjust() methods must return one of the codes below. + * + * The general data can be used by specializations + * to store state and control their heuristics. + */ + +typedef struct +{ + const char * name; + void * (*alloc) (void); + int (*init) (void * state, double eps_abs, double eps_rel, double a_y, double a_dydt); + int (*hadjust) (void * state, size_t dim, unsigned int ord, const double y[], const double yerr[], const double yp[], double * h); + void (*free) (void * state); +} +gsl_odeiv_control_type; + +typedef struct +{ + const gsl_odeiv_control_type * type; + void * state; +} +gsl_odeiv_control; + +/* Possible return values for an hadjust() evolution method. + */ +#define GSL_ODEIV_HADJ_INC 1 /* step was increased */ +#define GSL_ODEIV_HADJ_NIL 0 /* step unchanged */ +#define GSL_ODEIV_HADJ_DEC (-1) /* step decreased */ + +gsl_odeiv_control * gsl_odeiv_control_alloc(const gsl_odeiv_control_type * T); +int gsl_odeiv_control_init(gsl_odeiv_control * c, double eps_abs, double eps_rel, double a_y, double a_dydt); +void gsl_odeiv_control_free(gsl_odeiv_control * c); +int gsl_odeiv_control_hadjust (gsl_odeiv_control * c, gsl_odeiv_step * s, const double y[], const double yerr[], const double dydt[], double * h); +const char * gsl_odeiv_control_name(const gsl_odeiv_control * c); + +/* Available control object constructors. + * + * The standard control object is a four parameter heuristic + * defined as follows: + * D0 = eps_abs + eps_rel * (a_y |y| + a_dydt h |y'|) + * D1 = |yerr| + * q = consistency order of method (q=4 for 4(5) embedded RK) + * S = safety factor (0.9 say) + * + * / (D0/D1)^(1/(q+1)) D0 >= D1 + * h_NEW = S h_OLD * | + * \ (D0/D1)^(1/q) D0 < D1 + * + * This encompasses all the standard error scaling methods. + * + * The y method is the standard method with a_y=1, a_dydt=0. + * The yp method is the standard method with a_y=0, a_dydt=1. + */ + +gsl_odeiv_control * gsl_odeiv_control_standard_new(double eps_abs, double eps_rel, double a_y, double a_dydt); +gsl_odeiv_control * gsl_odeiv_control_y_new(double eps_abs, double eps_rel); +gsl_odeiv_control * gsl_odeiv_control_yp_new(double eps_abs, double eps_rel); + +/* This controller computes errors using different absolute errors for + * each component + * + * D0 = eps_abs * scale_abs[i] + eps_rel * (a_y |y| + a_dydt h |y'|) + */ +gsl_odeiv_control * gsl_odeiv_control_scaled_new(double eps_abs, double eps_rel, double a_y, double a_dydt, const double scale_abs[], size_t dim); + +/* General evolution object. + */ +typedef struct { + size_t dimension; + double * y0; + double * yerr; + double * dydt_in; + double * dydt_out; + double last_step; + unsigned long int count; + unsigned long int failed_steps; +} +gsl_odeiv_evolve; + +/* Evolution object methods. + */ +gsl_odeiv_evolve * gsl_odeiv_evolve_alloc(size_t dim); +int gsl_odeiv_evolve_apply(gsl_odeiv_evolve * e, gsl_odeiv_control * con, gsl_odeiv_step * step, const gsl_odeiv_system * dydt, double * t, double t1, double * h, double y[]); +int gsl_odeiv_evolve_reset(gsl_odeiv_evolve * e); +void gsl_odeiv_evolve_free(gsl_odeiv_evolve * e); + + +__END_DECLS + +#endif /* __GSL_ODEIV_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv2.h b/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv2.h new file mode 100644 index 0000000..9bcfbae --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_odeiv2.h @@ -0,0 +1,333 @@ +/* ode-initval/odeiv2.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ +/* Modified by Tuomo Keskitalo */ + +#ifndef __GSL_ODEIV2_H__ +#define __GSL_ODEIV2_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS +/* Description of a system of ODEs. + * + * y' = f(t,y) = dydt(t, y) + * + * The system is specified by giving the right-hand-side + * of the equation and possibly a jacobian function. + * + * Some methods require the jacobian function, which calculates + * the matrix dfdy and the vector dfdt. The matrix dfdy conforms + * to the GSL standard, being a continuous range of floating point + * values, in row-order. + * + * As with GSL function objects, user-supplied parameter + * data is also present. + */ + typedef struct +{ + int (*function) (double t, const double y[], double dydt[], void *params); + int (*jacobian) (double t, const double y[], double *dfdy, double dfdt[], + void *params); + size_t dimension; + void *params; +} +gsl_odeiv2_system; + +/* Function evaluation macros */ + +#define GSL_ODEIV_FN_EVAL(S,t,y,f) (*((S)->function))(t,y,f,(S)->params) +#define GSL_ODEIV_JA_EVAL(S,t,y,dfdy,dfdt) (*((S)->jacobian))(t,y,dfdy,dfdt,(S)->params) + +/* Type definitions */ + +typedef struct gsl_odeiv2_step_struct gsl_odeiv2_step; +typedef struct gsl_odeiv2_control_struct gsl_odeiv2_control; +typedef struct gsl_odeiv2_evolve_struct gsl_odeiv2_evolve; +typedef struct gsl_odeiv2_driver_struct gsl_odeiv2_driver; + +/* Stepper object + * + * Opaque object for stepping an ODE system from t to t+h. + * In general the object has some state which facilitates + * iterating the stepping operation. + */ + +typedef struct +{ + const char *name; + int can_use_dydt_in; + int gives_exact_dydt_out; + void *(*alloc) (size_t dim); + int (*apply) (void *state, size_t dim, double t, double h, double y[], + double yerr[], const double dydt_in[], double dydt_out[], + const gsl_odeiv2_system * dydt); + int (*set_driver) (void *state, const gsl_odeiv2_driver * d); + int (*reset) (void *state, size_t dim); + unsigned int (*order) (void *state); + void (*free) (void *state); +} +gsl_odeiv2_step_type; + +struct gsl_odeiv2_step_struct +{ + const gsl_odeiv2_step_type *type; + size_t dimension; + void *state; +}; + +/* Available stepper types */ + +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk2; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk4; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rkf45; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rkck; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk8pd; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk2imp; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk4imp; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_bsimp; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk1imp; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_msadams; +GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_msbdf; + +/* Stepper object methods */ + +gsl_odeiv2_step *gsl_odeiv2_step_alloc (const gsl_odeiv2_step_type * T, + size_t dim); +int gsl_odeiv2_step_reset (gsl_odeiv2_step * s); +void gsl_odeiv2_step_free (gsl_odeiv2_step * s); +const char *gsl_odeiv2_step_name (const gsl_odeiv2_step * s); +unsigned int gsl_odeiv2_step_order (const gsl_odeiv2_step * s); +int gsl_odeiv2_step_apply (gsl_odeiv2_step * s, double t, double h, + double y[], double yerr[], const double dydt_in[], + double dydt_out[], const gsl_odeiv2_system * dydt); +int gsl_odeiv2_step_set_driver (gsl_odeiv2_step * s, + const gsl_odeiv2_driver * d); + +/* Step size control object. */ + +typedef struct +{ + const char *name; + void *(*alloc) (void); + int (*init) (void *state, double eps_abs, double eps_rel, double a_y, + double a_dydt); + int (*hadjust) (void *state, size_t dim, unsigned int ord, const double y[], + const double yerr[], const double yp[], double *h); + int (*errlevel) (void *state, const double y, const double dydt, + const double h, const size_t ind, double *errlev); + int (*set_driver) (void *state, const gsl_odeiv2_driver * d); + void (*free) (void *state); +} +gsl_odeiv2_control_type; + +struct gsl_odeiv2_control_struct +{ + const gsl_odeiv2_control_type *type; + void *state; +}; + +/* Possible return values for an hadjust() evolution method */ + +#define GSL_ODEIV_HADJ_INC 1 /* step was increased */ +#define GSL_ODEIV_HADJ_NIL 0 /* step unchanged */ +#define GSL_ODEIV_HADJ_DEC (-1) /* step decreased */ + +/* General step size control methods. + * + * The hadjust() method controls the adjustment of + * step size given the result of a step and the error. + * Valid hadjust() methods must return one of the codes below. + * errlevel function calculates the desired error level D0. + * + * The general data can be used by specializations + * to store state and control their heuristics. + */ + +gsl_odeiv2_control *gsl_odeiv2_control_alloc (const gsl_odeiv2_control_type * + T); +int gsl_odeiv2_control_init (gsl_odeiv2_control * c, double eps_abs, + double eps_rel, double a_y, double a_dydt); +void gsl_odeiv2_control_free (gsl_odeiv2_control * c); +int gsl_odeiv2_control_hadjust (gsl_odeiv2_control * c, gsl_odeiv2_step * s, + const double y[], const double yerr[], + const double dydt[], double *h); +const char *gsl_odeiv2_control_name (const gsl_odeiv2_control * c); +int gsl_odeiv2_control_errlevel (gsl_odeiv2_control * c, const double y, + const double dydt, const double h, + const size_t ind, double *errlev); +int gsl_odeiv2_control_set_driver (gsl_odeiv2_control * c, + const gsl_odeiv2_driver * d); + +/* Available control object constructors. + * + * The standard control object is a four parameter heuristic + * defined as follows: + * D0 = eps_abs + eps_rel * (a_y |y| + a_dydt h |y'|) + * D1 = |yerr| + * q = consistency order of method (q=4 for 4(5) embedded RK) + * S = safety factor (0.9 say) + * + * / (D0/D1)^(1/(q+1)) D0 >= D1 + * h_NEW = S h_OLD * | + * \ (D0/D1)^(1/q) D0 < D1 + * + * This encompasses all the standard error scaling methods. + * + * The y method is the standard method with a_y=1, a_dydt=0. + * The yp method is the standard method with a_y=0, a_dydt=1. + */ + +gsl_odeiv2_control *gsl_odeiv2_control_standard_new (double eps_abs, + double eps_rel, + double a_y, + double a_dydt); +gsl_odeiv2_control *gsl_odeiv2_control_y_new (double eps_abs, double eps_rel); +gsl_odeiv2_control *gsl_odeiv2_control_yp_new (double eps_abs, + double eps_rel); + +/* This controller computes errors using different absolute errors for + * each component + * + * D0 = eps_abs * scale_abs[i] + eps_rel * (a_y |y| + a_dydt h |y'|) + */ + +gsl_odeiv2_control *gsl_odeiv2_control_scaled_new (double eps_abs, + double eps_rel, double a_y, + double a_dydt, + const double scale_abs[], + size_t dim); + +/* Evolution object */ + +struct gsl_odeiv2_evolve_struct +{ + size_t dimension; + double *y0; + double *yerr; + double *dydt_in; + double *dydt_out; + double last_step; + unsigned long int count; + unsigned long int failed_steps; + const gsl_odeiv2_driver *driver; +}; + +/* Evolution object methods */ + +gsl_odeiv2_evolve *gsl_odeiv2_evolve_alloc (size_t dim); +int gsl_odeiv2_evolve_apply (gsl_odeiv2_evolve * e, gsl_odeiv2_control * con, + gsl_odeiv2_step * step, + const gsl_odeiv2_system * dydt, double *t, + double t1, double *h, double y[]); +int gsl_odeiv2_evolve_apply_fixed_step (gsl_odeiv2_evolve * e, + gsl_odeiv2_control * con, + gsl_odeiv2_step * step, + const gsl_odeiv2_system * dydt, + double *t, const double h0, + double y[]); +int gsl_odeiv2_evolve_reset (gsl_odeiv2_evolve * e); +void gsl_odeiv2_evolve_free (gsl_odeiv2_evolve * e); +int gsl_odeiv2_evolve_set_driver (gsl_odeiv2_evolve * e, + const gsl_odeiv2_driver * d); + +/* Driver object + * + * This is a high level wrapper for step, control and + * evolve objects. + */ + +struct gsl_odeiv2_driver_struct +{ + const gsl_odeiv2_system *sys; /* ODE system */ + gsl_odeiv2_step *s; /* stepper object */ + gsl_odeiv2_control *c; /* control object */ + gsl_odeiv2_evolve *e; /* evolve object */ + double h; /* step size */ + double hmin; /* minimum step size allowed */ + double hmax; /* maximum step size allowed */ + unsigned long int n; /* number of steps taken */ + unsigned long int nmax; /* Maximum number of steps allowed */ +}; + +/* Driver object methods */ + +gsl_odeiv2_driver *gsl_odeiv2_driver_alloc_y_new (const gsl_odeiv2_system * + sys, + const gsl_odeiv2_step_type * + T, const double hstart, + const double epsabs, + const double epsrel); +gsl_odeiv2_driver *gsl_odeiv2_driver_alloc_yp_new (const gsl_odeiv2_system * + sys, + const gsl_odeiv2_step_type + * T, const double hstart, + const double epsabs, + const double epsrel); +gsl_odeiv2_driver *gsl_odeiv2_driver_alloc_scaled_new (const gsl_odeiv2_system + * sys, + const + gsl_odeiv2_step_type * + T, const double hstart, + const double epsabs, + const double epsrel, + const double a_y, + const double a_dydt, + const double + scale_abs[]); +gsl_odeiv2_driver *gsl_odeiv2_driver_alloc_standard_new (const + gsl_odeiv2_system * + sys, + const + gsl_odeiv2_step_type + * T, + const double hstart, + const double epsabs, + const double epsrel, + const double a_y, + const double a_dydt); +int gsl_odeiv2_driver_set_hmin (gsl_odeiv2_driver * d, const double hmin); +int gsl_odeiv2_driver_set_hmax (gsl_odeiv2_driver * d, const double hmax); +int gsl_odeiv2_driver_set_nmax (gsl_odeiv2_driver * d, + const unsigned long int nmax); +int gsl_odeiv2_driver_apply (gsl_odeiv2_driver * d, double *t, + const double t1, double y[]); +int gsl_odeiv2_driver_apply_fixed_step (gsl_odeiv2_driver * d, double *t, + const double h, + const unsigned long int n, + double y[]); +int gsl_odeiv2_driver_reset (gsl_odeiv2_driver * d); +int gsl_odeiv2_driver_reset_hstart (gsl_odeiv2_driver * d, const double hstart); +void gsl_odeiv2_driver_free (gsl_odeiv2_driver * state); + +__END_DECLS +#endif /* __GSL_ODEIV2_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permutation.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permutation.h new file mode 100644 index 0000000..10ac0f5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permutation.h @@ -0,0 +1,100 @@ +/* permutation/gsl_permutation.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTATION_H__ +#define __GSL_PERMUTATION_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_permutation_struct +{ + size_t size; + size_t *data; +}; + +typedef struct gsl_permutation_struct gsl_permutation; + +gsl_permutation *gsl_permutation_alloc (const size_t n); +gsl_permutation *gsl_permutation_calloc (const size_t n); +void gsl_permutation_init (gsl_permutation * p); +void gsl_permutation_free (gsl_permutation * p); +int gsl_permutation_memcpy (gsl_permutation * dest, const gsl_permutation * src); + +int gsl_permutation_fread (FILE * stream, gsl_permutation * p); +int gsl_permutation_fwrite (FILE * stream, const gsl_permutation * p); +int gsl_permutation_fscanf (FILE * stream, gsl_permutation * p); +int gsl_permutation_fprintf (FILE * stream, const gsl_permutation * p, const char *format); + +size_t gsl_permutation_size (const gsl_permutation * p); +size_t * gsl_permutation_data (const gsl_permutation * p); + +int gsl_permutation_swap (gsl_permutation * p, const size_t i, const size_t j); + +int gsl_permutation_valid (const gsl_permutation * p); +void gsl_permutation_reverse (gsl_permutation * p); +int gsl_permutation_inverse (gsl_permutation * inv, const gsl_permutation * p); +int gsl_permutation_next (gsl_permutation * p); +int gsl_permutation_prev (gsl_permutation * p); +int gsl_permutation_mul (gsl_permutation * p, const gsl_permutation * pa, const gsl_permutation * pb); + +int gsl_permutation_linear_to_canonical (gsl_permutation * q, const gsl_permutation * p); +int gsl_permutation_canonical_to_linear (gsl_permutation * p, const gsl_permutation * q); + +size_t gsl_permutation_inversions (const gsl_permutation * p); +size_t gsl_permutation_linear_cycles (const gsl_permutation * p); +size_t gsl_permutation_canonical_cycles (const gsl_permutation * q); + +INLINE_DECL size_t gsl_permutation_get (const gsl_permutation * p, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +size_t +gsl_permutation_get (const gsl_permutation * p, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= p->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return p->data[i]; +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_PERMUTATION_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute.h new file mode 100644 index 0000000..23f09a6 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute.h @@ -0,0 +1,24 @@ +#ifndef __GSL_PERMUTE_H__ +#define __GSL_PERMUTE_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_PERMUTE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_char.h new file mode 100644 index 0000000..bf2ebb1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_char.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_CHAR_H__ +#define __GSL_PERMUTE_CHAR_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_char (const size_t * p, char * data, const size_t stride, const size_t n); +int gsl_permute_char_inverse (const size_t * p, char * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_double.h new file mode 100644 index 0000000..c20442b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_complex_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_COMPLEX_DOUBLE_H__ +#define __GSL_PERMUTE_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_complex (const size_t * p, double * data, const size_t stride, const size_t n); +int gsl_permute_complex_inverse (const size_t * p, double * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_float.h new file mode 100644 index 0000000..65ee0fe --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_float.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_COMPLEX_FLOAT_H__ +#define __GSL_PERMUTE_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_complex_float (const size_t * p, float * data, const size_t stride, const size_t n); +int gsl_permute_complex_float_inverse (const size_t * p, float * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_long_double.h new file mode 100644 index 0000000..4849b15 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_complex_long_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_complex_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_complex_long_double (const size_t * p, long double * data, const size_t stride, const size_t n); +int gsl_permute_complex_long_double_inverse (const size_t * p, long double * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_double.h new file mode 100644 index 0000000..58be181 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_DOUBLE_H__ +#define __GSL_PERMUTE_DOUBLE_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute (const size_t * p, double * data, const size_t stride, const size_t n); +int gsl_permute_inverse (const size_t * p, double * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_float.h new file mode 100644 index 0000000..bc79bd5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_float.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_FLOAT_H__ +#define __GSL_PERMUTE_FLOAT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_float (const size_t * p, float * data, const size_t stride, const size_t n); +int gsl_permute_float_inverse (const size_t * p, float * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_int.h new file mode 100644 index 0000000..b6ff500 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_int.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_INT_H__ +#define __GSL_PERMUTE_INT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_int (const size_t * p, int * data, const size_t stride, const size_t n); +int gsl_permute_int_inverse (const size_t * p, int * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long.h new file mode 100644 index 0000000..383294c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_LONG_H__ +#define __GSL_PERMUTE_LONG_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_long (const size_t * p, long * data, const size_t stride, const size_t n); +int gsl_permute_long_inverse (const size_t * p, long * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long_double.h new file mode 100644 index 0000000..f58e1cd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_long_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_LONG_DOUBLE_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_long_double (const size_t * p, long double * data, const size_t stride, const size_t n); +int gsl_permute_long_double_inverse (const size_t * p, long double * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix.h new file mode 100644 index 0000000..aa8e672 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix.h @@ -0,0 +1,24 @@ +#ifndef __GSL_PERMUTE_MATRIX_H__ +#define __GSL_PERMUTE_MATRIX_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_PERMUTE_MATRIX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_char.h new file mode 100644 index 0000000..7ce67aa --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_char.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_char.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_CHAR_H__ +#define __GSL_PERMUTE_MATRIX_CHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_char (const gsl_permutation * p, gsl_matrix_char * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_double.h new file mode 100644 index 0000000..0c047b4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_complex_double.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_COMPLEX_DOUBLE_H__ +#define __GSL_PERMUTE_MATRIX_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_complex (const gsl_permutation * p, gsl_matrix_complex * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_float.h new file mode 100644 index 0000000..c0a7a94 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_float.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_complex_float.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_COMPLEX_FLOAT_H__ +#define __GSL_PERMUTE_MATRIX_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_complex_float (const gsl_permutation * p, gsl_matrix_complex_float * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_long_double.h new file mode 100644 index 0000000..a005e96 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_complex_long_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_complex_long_double.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_MATRIX_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_complex_long_double (const gsl_permutation * p, gsl_matrix_complex_long_double * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_double.h new file mode 100644 index 0000000..2f17bd8 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_double.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_DOUBLE_H__ +#define __GSL_PERMUTE_MATRIX_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix (const gsl_permutation * p, gsl_matrix * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_float.h new file mode 100644 index 0000000..7003622 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_float.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_float.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_FLOAT_H__ +#define __GSL_PERMUTE_MATRIX_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_float (const gsl_permutation * p, gsl_matrix_float * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_int.h new file mode 100644 index 0000000..27dfea0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_int.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_int.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_INT_H__ +#define __GSL_PERMUTE_MATRIX_INT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_int (const gsl_permutation * p, gsl_matrix_int * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long.h new file mode 100644 index 0000000..6aaaaf4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_long.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_LONG_H__ +#define __GSL_PERMUTE_MATRIX_LONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_long (const gsl_permutation * p, gsl_matrix_long * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long_double.h new file mode 100644 index 0000000..8a7d28c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_long_double.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_long_double.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_MATRIX_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_long_double (const gsl_permutation * p, gsl_matrix_long_double * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_short.h new file mode 100644 index 0000000..1982305 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_short.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_short.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_SHORT_H__ +#define __GSL_PERMUTE_MATRIX_SHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_short (const gsl_permutation * p, gsl_matrix_short * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uchar.h new file mode 100644 index 0000000..95991bf --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uchar.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_uchar.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_UCHAR_H__ +#define __GSL_PERMUTE_MATRIX_UCHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_uchar (const gsl_permutation * p, gsl_matrix_uchar * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uint.h new file mode 100644 index 0000000..6497809 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_uint.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_uint.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_UINT_H__ +#define __GSL_PERMUTE_MATRIX_UINT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_uint (const gsl_permutation * p, gsl_matrix_uint * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ulong.h new file mode 100644 index 0000000..5aabc47 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ulong.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_ulong.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_ULONG_H__ +#define __GSL_PERMUTE_MATRIX_ULONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_ulong (const gsl_permutation * p, gsl_matrix_ulong * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ushort.h new file mode 100644 index 0000000..e432ffe --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_matrix_ushort.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_matrix_ushort.h + * + * Copyright (C) 2016 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_MATRIX_USHORT_H__ +#define __GSL_PERMUTE_MATRIX_USHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_matrix_ushort (const gsl_permutation * p, gsl_matrix_ushort * A); + +__END_DECLS + +#endif /* __GSL_PERMUTE_MATRIX_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_short.h new file mode 100644 index 0000000..39cf55d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_short.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_SHORT_H__ +#define __GSL_PERMUTE_SHORT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_short (const size_t * p, short * data, const size_t stride, const size_t n); +int gsl_permute_short_inverse (const size_t * p, short * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uchar.h new file mode 100644 index 0000000..54bb401 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uchar.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_UCHAR_H__ +#define __GSL_PERMUTE_UCHAR_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_uchar (const size_t * p, unsigned char * data, const size_t stride, const size_t n); +int gsl_permute_uchar_inverse (const size_t * p, unsigned char * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uint.h new file mode 100644 index 0000000..8915b7b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_uint.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_UINT_H__ +#define __GSL_PERMUTE_UINT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_uint (const size_t * p, unsigned int * data, const size_t stride, const size_t n); +int gsl_permute_uint_inverse (const size_t * p, unsigned int * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ulong.h new file mode 100644 index 0000000..0084c50 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ulong.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_ULONG_H__ +#define __GSL_PERMUTE_ULONG_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_ulong (const size_t * p, unsigned long * data, const size_t stride, const size_t n); +int gsl_permute_ulong_inverse (const size_t * p, unsigned long * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ushort.h new file mode 100644 index 0000000..eff079a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_ushort.h @@ -0,0 +1,44 @@ +/* permutation/gsl_permute_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_USHORT_H__ +#define __GSL_PERMUTE_USHORT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_ushort (const size_t * p, unsigned short * data, const size_t stride, const size_t n); +int gsl_permute_ushort_inverse (const size_t * p, unsigned short * data, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_PERMUTE_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector.h new file mode 100644 index 0000000..4369e49 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector.h @@ -0,0 +1,24 @@ +#ifndef __GSL_PERMUTE_VECTOR_H__ +#define __GSL_PERMUTE_VECTOR_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_PERMUTE_VECTOR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_char.h new file mode 100644 index 0000000..15278ed --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_char.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_CHAR_H__ +#define __GSL_PERMUTE_VECTOR_CHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_char (const gsl_permutation * p, gsl_vector_char * v); +int gsl_permute_vector_char_inverse (const gsl_permutation * p, gsl_vector_char * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_double.h new file mode 100644 index 0000000..60558e2 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_complex_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ +#define __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_complex (const gsl_permutation * p, gsl_vector_complex * v); +int gsl_permute_vector_complex_inverse (const gsl_permutation * p, gsl_vector_complex * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_float.h new file mode 100644 index 0000000..b08696b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_float.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ +#define __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_complex_float (const gsl_permutation * p, gsl_vector_complex_float * v); +int gsl_permute_vector_complex_float_inverse (const gsl_permutation * p, gsl_vector_complex_float * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_long_double.h new file mode 100644 index 0000000..c19ac25 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_complex_long_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_complex_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_complex_long_double (const gsl_permutation * p, gsl_vector_complex_long_double * v); +int gsl_permute_vector_complex_long_double_inverse (const gsl_permutation * p, gsl_vector_complex_long_double * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_double.h new file mode 100644 index 0000000..65f6167 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_DOUBLE_H__ +#define __GSL_PERMUTE_VECTOR_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector (const gsl_permutation * p, gsl_vector * v); +int gsl_permute_vector_inverse (const gsl_permutation * p, gsl_vector * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_float.h new file mode 100644 index 0000000..bdd9d1a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_float.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_FLOAT_H__ +#define __GSL_PERMUTE_VECTOR_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_float (const gsl_permutation * p, gsl_vector_float * v); +int gsl_permute_vector_float_inverse (const gsl_permutation * p, gsl_vector_float * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_int.h new file mode 100644 index 0000000..3316d50 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_int.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_INT_H__ +#define __GSL_PERMUTE_VECTOR_INT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_int (const gsl_permutation * p, gsl_vector_int * v); +int gsl_permute_vector_int_inverse (const gsl_permutation * p, gsl_vector_int * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long.h new file mode 100644 index 0000000..291f949 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_LONG_H__ +#define __GSL_PERMUTE_VECTOR_LONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_long (const gsl_permutation * p, gsl_vector_long * v); +int gsl_permute_vector_long_inverse (const gsl_permutation * p, gsl_vector_long * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long_double.h new file mode 100644 index 0000000..a6b0296 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_long_double.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ +#define __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_long_double (const gsl_permutation * p, gsl_vector_long_double * v); +int gsl_permute_vector_long_double_inverse (const gsl_permutation * p, gsl_vector_long_double * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_short.h new file mode 100644 index 0000000..cd0dd6b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_short.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_SHORT_H__ +#define __GSL_PERMUTE_VECTOR_SHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_short (const gsl_permutation * p, gsl_vector_short * v); +int gsl_permute_vector_short_inverse (const gsl_permutation * p, gsl_vector_short * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uchar.h new file mode 100644 index 0000000..df069a0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uchar.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_UCHAR_H__ +#define __GSL_PERMUTE_VECTOR_UCHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_uchar (const gsl_permutation * p, gsl_vector_uchar * v); +int gsl_permute_vector_uchar_inverse (const gsl_permutation * p, gsl_vector_uchar * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uint.h new file mode 100644 index 0000000..ee5218a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_uint.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_UINT_H__ +#define __GSL_PERMUTE_VECTOR_UINT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_uint (const gsl_permutation * p, gsl_vector_uint * v); +int gsl_permute_vector_uint_inverse (const gsl_permutation * p, gsl_vector_uint * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ulong.h new file mode 100644 index 0000000..e536d9a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ulong.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_ULONG_H__ +#define __GSL_PERMUTE_VECTOR_ULONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_ulong (const gsl_permutation * p, gsl_vector_ulong * v); +int gsl_permute_vector_ulong_inverse (const gsl_permutation * p, gsl_vector_ulong * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ushort.h new file mode 100644 index 0000000..7533ba0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_permute_vector_ushort.h @@ -0,0 +1,45 @@ +/* permutation/gsl_permute_vector_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_PERMUTE_VECTOR_USHORT_H__ +#define __GSL_PERMUTE_VECTOR_USHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_permute_vector_ushort (const gsl_permutation * p, gsl_vector_ushort * v); +int gsl_permute_vector_ushort_inverse (const gsl_permutation * p, gsl_vector_ushort * v); + +__END_DECLS + +#endif /* __GSL_PERMUTE_VECTOR_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_poly.h b/ChaosDataPlayer/GSL/include/gsl/gsl_poly.h new file mode 100644 index 0000000..2352857 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_poly.h @@ -0,0 +1,183 @@ +/* poly/gsl_poly.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_POLY_H__ +#define __GSL_POLY_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Evaluate polynomial + * + * c[0] + c[1] x + c[2] x^2 + ... + c[len-1] x^(len-1) + * + * exceptions: none + */ + +/* real polynomial, real x */ +INLINE_DECL double gsl_poly_eval(const double c[], const int len, const double x); + +/* real polynomial, complex x */ +INLINE_DECL gsl_complex gsl_poly_complex_eval (const double c [], const int len, const gsl_complex z); + +/* complex polynomial, complex x */ +INLINE_DECL gsl_complex gsl_complex_poly_complex_eval (const gsl_complex c [], const int len, const gsl_complex z); + +int gsl_poly_eval_derivs(const double c[], const size_t lenc, const double x, double res[], const size_t lenres); + +#ifdef HAVE_INLINE +INLINE_FUN +double +gsl_poly_eval(const double c[], const int len, const double x) +{ + int i; + double ans = c[len-1]; + for(i=len-1; i>0; i--) ans = c[i-1] + x * ans; + return ans; +} + +INLINE_FUN +gsl_complex +gsl_poly_complex_eval(const double c[], const int len, const gsl_complex z) +{ + int i; + gsl_complex ans; + GSL_SET_COMPLEX (&ans, c[len-1], 0.0); + for(i=len-1; i>0; i--) { + /* The following three lines are equivalent to + ans = gsl_complex_add_real (gsl_complex_mul (z, ans), c[i-1]); + but faster */ + double tmp = c[i-1] + GSL_REAL (z) * GSL_REAL (ans) - GSL_IMAG (z) * GSL_IMAG (ans); + GSL_SET_IMAG (&ans, GSL_IMAG (z) * GSL_REAL (ans) + GSL_REAL (z) * GSL_IMAG (ans)); + GSL_SET_REAL (&ans, tmp); + } + return ans; +} + +INLINE_FUN +gsl_complex +gsl_complex_poly_complex_eval(const gsl_complex c[], const int len, const gsl_complex z) +{ + int i; + gsl_complex ans = c[len-1]; + for(i=len-1; i>0; i--) { + /* The following three lines are equivalent to + ans = gsl_complex_add (c[i-1], gsl_complex_mul (x, ans)); + but faster */ + double tmp = GSL_REAL (c[i-1]) + GSL_REAL (z) * GSL_REAL (ans) - GSL_IMAG (z) * GSL_IMAG (ans); + GSL_SET_IMAG (&ans, GSL_IMAG (c[i-1]) + GSL_IMAG (z) * GSL_REAL (ans) + GSL_REAL (z) * GSL_IMAG (ans)); + GSL_SET_REAL (&ans, tmp); + } + return ans; +} +#endif /* HAVE_INLINE */ + +/* Work with divided-difference polynomials, Abramowitz & Stegun 25.2.26 */ + +int +gsl_poly_dd_init (double dd[], const double x[], const double y[], + size_t size); + +INLINE_DECL double +gsl_poly_dd_eval (const double dd[], const double xa[], const size_t size, const double x); + +#ifdef HAVE_INLINE +INLINE_FUN +double +gsl_poly_dd_eval(const double dd[], const double xa[], const size_t size, const double x) +{ + size_t i; + double y = dd[size - 1]; + for (i = size - 1; i--;) y = dd[i] + (x - xa[i]) * y; + return y; +} +#endif /* HAVE_INLINE */ + + +int +gsl_poly_dd_taylor (double c[], double xp, + const double dd[], const double x[], size_t size, + double w[]); + +int +gsl_poly_dd_hermite_init (double dd[], double z[], const double xa[], const double ya[], + const double dya[], const size_t size); + +/* Solve for real or complex roots of the standard quadratic equation, + * returning the number of real roots. + * + * Roots are returned ordered. + */ +int gsl_poly_solve_quadratic (double a, double b, double c, + double * x0, double * x1); + +int +gsl_poly_complex_solve_quadratic (double a, double b, double c, + gsl_complex * z0, gsl_complex * z1); + + +/* Solve for real roots of the cubic equation + * x^3 + a x^2 + b x + c = 0, returning the + * number of real roots. + * + * Roots are returned ordered. + */ +int gsl_poly_solve_cubic (double a, double b, double c, + double * x0, double * x1, double * x2); + +int +gsl_poly_complex_solve_cubic (double a, double b, double c, + gsl_complex * z0, gsl_complex * z1, + gsl_complex * z2); + + +/* Solve for the complex roots of a general real polynomial */ + +typedef struct +{ + size_t nc ; + double * matrix ; +} +gsl_poly_complex_workspace ; + +gsl_poly_complex_workspace * gsl_poly_complex_workspace_alloc (size_t n); +void gsl_poly_complex_workspace_free (gsl_poly_complex_workspace * w); + +int +gsl_poly_complex_solve (const double * a, size_t n, + gsl_poly_complex_workspace * w, + gsl_complex_packed_ptr z); + +__END_DECLS + +#endif /* __GSL_POLY_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_pow_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_pow_int.h new file mode 100644 index 0000000..6aa01fb --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_pow_int.h @@ -0,0 +1,61 @@ +/* gsl_pow_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_POW_INT_H__ +#define __GSL_POW_INT_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +INLINE_DECL double gsl_pow_2(const double x); +INLINE_DECL double gsl_pow_3(const double x); +INLINE_DECL double gsl_pow_4(const double x); +INLINE_DECL double gsl_pow_5(const double x); +INLINE_DECL double gsl_pow_6(const double x); +INLINE_DECL double gsl_pow_7(const double x); +INLINE_DECL double gsl_pow_8(const double x); +INLINE_DECL double gsl_pow_9(const double x); + +#ifdef HAVE_INLINE +INLINE_FUN double gsl_pow_2(const double x) { return x*x; } +INLINE_FUN double gsl_pow_3(const double x) { return x*x*x; } +INLINE_FUN double gsl_pow_4(const double x) { double x2 = x*x; return x2*x2; } +INLINE_FUN double gsl_pow_5(const double x) { double x2 = x*x; return x2*x2*x; } +INLINE_FUN double gsl_pow_6(const double x) { double x2 = x*x; return x2*x2*x2; } +INLINE_FUN double gsl_pow_7(const double x) { double x3 = x*x*x; return x3*x3*x; } +INLINE_FUN double gsl_pow_8(const double x) { double x2 = x*x; double x4 = x2*x2; return x4*x4; } +INLINE_FUN double gsl_pow_9(const double x) { double x3 = x*x*x; return x3*x3*x3; } +#endif + +double gsl_pow_int(double x, int n); +double gsl_pow_uint(double x, unsigned int n); + +__END_DECLS + +#endif /* __GSL_POW_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_precision.h b/ChaosDataPlayer/GSL/include/gsl/gsl_precision.h new file mode 100644 index 0000000..97a204e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_precision.h @@ -0,0 +1,66 @@ +/* gsl_precision.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: B. Gough and G. Jungman */ + +#ifndef __GSL_PRECISION_H__ +#define __GSL_PRECISION_H__ +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* A type for the precision indicator. + * This is mainly for pedagogy. + */ +typedef unsigned int gsl_prec_t; + + +/* The number of precision types. + * Remember that precision-mode + * can index an array. + */ +#define _GSL_PREC_T_NUM 3 + + +/* Arrays containing derived + * precision constants for the + * different precision levels. + */ +GSL_VAR const double gsl_prec_eps[]; +GSL_VAR const double gsl_prec_sqrt_eps[]; +GSL_VAR const double gsl_prec_root3_eps[]; +GSL_VAR const double gsl_prec_root4_eps[]; +GSL_VAR const double gsl_prec_root5_eps[]; +GSL_VAR const double gsl_prec_root6_eps[]; + + +__END_DECLS + +#endif /* __GSL_PRECISION_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_qrng.h b/ChaosDataPlayer/GSL/include/gsl/gsl_qrng.h new file mode 100644 index 0000000..47de500 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_qrng.h @@ -0,0 +1,111 @@ +/* Author: G. Jungman + modifications from O. Teytaud + */ +#ifndef __GSL_QRNG_H__ +#define __GSL_QRNG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Once again, more inane C-style OOP... kill me now. */ + +/* Structure describing a type of generator. + */ +typedef struct +{ + const char * name; + unsigned int max_dimension; + size_t (*state_size) (unsigned int dimension); + int (*init_state) (void * state, unsigned int dimension); + int (*get) (void * state, unsigned int dimension, double x[]); +} +gsl_qrng_type; + +/* Structure describing a generator instance of a + * specified type, with generator-specific state info + * and dimension-specific info. + */ +typedef struct +{ + const gsl_qrng_type * type; + unsigned int dimension; + size_t state_size; + void * state; +} +gsl_qrng; + + +/* Supported generator types. + */ +GSL_VAR const gsl_qrng_type * gsl_qrng_niederreiter_2; +GSL_VAR const gsl_qrng_type * gsl_qrng_sobol; +GSL_VAR const gsl_qrng_type * gsl_qrng_halton; +GSL_VAR const gsl_qrng_type * gsl_qrng_reversehalton; + + +/* Allocate and initialize a generator + * of the specified type, in the given + * space dimension. + */ +gsl_qrng * gsl_qrng_alloc (const gsl_qrng_type * T, unsigned int dimension); + + +/* Copy a generator. */ +int gsl_qrng_memcpy (gsl_qrng * dest, const gsl_qrng * src); + + +/* Clone a generator. */ +gsl_qrng * gsl_qrng_clone (const gsl_qrng * q); + + +/* Free a generator. */ +void gsl_qrng_free (gsl_qrng * q); + + +/* Intialize a generator. */ +void gsl_qrng_init (gsl_qrng * q); + + +/* Get the standardized name of the generator. */ +const char * gsl_qrng_name (const gsl_qrng * q); + + +/* ISN'T THIS CONFUSING FOR PEOPLE? + WHAT IF SOMEBODY TRIES TO COPY WITH THIS ??? + */ +size_t gsl_qrng_size (const gsl_qrng * q); + + +void * gsl_qrng_state (const gsl_qrng * q); + + +/* Retrieve next vector in sequence. */ +INLINE_DECL int gsl_qrng_get (const gsl_qrng * q, double x[]); + +#ifdef HAVE_INLINE +INLINE_FUN int gsl_qrng_get (const gsl_qrng * q, double x[]) +{ + return (q->type->get) (q->state, q->dimension, x); +} + +#endif /* HAVE_INLINE */ + + +__END_DECLS + + +#endif /* !__GSL_QRNG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_randist.h b/ChaosDataPlayer/GSL/include/gsl/gsl_randist.h new file mode 100644 index 0000000..d38ccb3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_randist.h @@ -0,0 +1,219 @@ +/* randist/gsl_randist.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_RANDIST_H__ +#define __GSL_RANDIST_H__ +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +unsigned int gsl_ran_bernoulli (const gsl_rng * r, double p); +double gsl_ran_bernoulli_pdf (const unsigned int k, double p); + +double gsl_ran_beta (const gsl_rng * r, const double a, const double b); +double gsl_ran_beta_pdf (const double x, const double a, const double b); + +unsigned int gsl_ran_binomial (const gsl_rng * r, double p, unsigned int n); +unsigned int gsl_ran_binomial_knuth (const gsl_rng * r, double p, unsigned int n); +unsigned int gsl_ran_binomial_tpe (const gsl_rng * r, double p, unsigned int n); +double gsl_ran_binomial_pdf (const unsigned int k, const double p, const unsigned int n); + +double gsl_ran_exponential (const gsl_rng * r, const double mu); +double gsl_ran_exponential_pdf (const double x, const double mu); + +double gsl_ran_exppow (const gsl_rng * r, const double a, const double b); +double gsl_ran_exppow_pdf (const double x, const double a, const double b); + +double gsl_ran_cauchy (const gsl_rng * r, const double a); +double gsl_ran_cauchy_pdf (const double x, const double a); + +double gsl_ran_chisq (const gsl_rng * r, const double nu); +double gsl_ran_chisq_pdf (const double x, const double nu); + +void gsl_ran_dirichlet (const gsl_rng * r, const size_t K, const double alpha[], double theta[]); +double gsl_ran_dirichlet_pdf (const size_t K, const double alpha[], const double theta[]); +double gsl_ran_dirichlet_lnpdf (const size_t K, const double alpha[], const double theta[]); + +double gsl_ran_erlang (const gsl_rng * r, const double a, const double n); +double gsl_ran_erlang_pdf (const double x, const double a, const double n); + +double gsl_ran_fdist (const gsl_rng * r, const double nu1, const double nu2); +double gsl_ran_fdist_pdf (const double x, const double nu1, const double nu2); + +double gsl_ran_flat (const gsl_rng * r, const double a, const double b); +double gsl_ran_flat_pdf (double x, const double a, const double b); + +double gsl_ran_gamma (const gsl_rng * r, const double a, const double b); +double gsl_ran_gamma_int (const gsl_rng * r, const unsigned int a); +double gsl_ran_gamma_pdf (const double x, const double a, const double b); +double gsl_ran_gamma_mt (const gsl_rng * r, const double a, const double b); +double gsl_ran_gamma_knuth (const gsl_rng * r, const double a, const double b); + +double gsl_ran_gaussian (const gsl_rng * r, const double sigma); +double gsl_ran_gaussian_ratio_method (const gsl_rng * r, const double sigma); +double gsl_ran_gaussian_ziggurat (const gsl_rng * r, const double sigma); +double gsl_ran_gaussian_pdf (const double x, const double sigma); + +double gsl_ran_ugaussian (const gsl_rng * r); +double gsl_ran_ugaussian_ratio_method (const gsl_rng * r); +double gsl_ran_ugaussian_pdf (const double x); + +double gsl_ran_gaussian_tail (const gsl_rng * r, const double a, const double sigma); +double gsl_ran_gaussian_tail_pdf (const double x, const double a, const double sigma); + +double gsl_ran_ugaussian_tail (const gsl_rng * r, const double a); +double gsl_ran_ugaussian_tail_pdf (const double x, const double a); + +void gsl_ran_bivariate_gaussian (const gsl_rng * r, double sigma_x, double sigma_y, double rho, double *x, double *y); +double gsl_ran_bivariate_gaussian_pdf (const double x, const double y, const double sigma_x, const double sigma_y, const double rho); + +int gsl_ran_multivariate_gaussian (const gsl_rng * r, const gsl_vector * mu, const gsl_matrix * L, gsl_vector * result); +int gsl_ran_multivariate_gaussian_log_pdf (const gsl_vector * x, + const gsl_vector * mu, + const gsl_matrix * L, + double * result, + gsl_vector * work); +int gsl_ran_multivariate_gaussian_pdf (const gsl_vector * x, + const gsl_vector * mu, + const gsl_matrix * L, + double * result, + gsl_vector * work); +int gsl_ran_multivariate_gaussian_mean (const gsl_matrix * X, gsl_vector * mu_hat); +int gsl_ran_multivariate_gaussian_vcov (const gsl_matrix * X, gsl_matrix * sigma_hat); + +int gsl_ran_wishart (const gsl_rng * r, + const double df, + const gsl_matrix * L, + gsl_matrix * result, + gsl_matrix * work); +int gsl_ran_wishart_log_pdf (const gsl_matrix * X, + const gsl_matrix * L_X, + const double df, + const gsl_matrix * L, + double * result, + gsl_matrix * work); +int gsl_ran_wishart_pdf (const gsl_matrix * X, + const gsl_matrix * L_X, + const double df, + const gsl_matrix * L, + double * result, + gsl_matrix * work); + +double gsl_ran_landau (const gsl_rng * r); +double gsl_ran_landau_pdf (const double x); + +unsigned int gsl_ran_geometric (const gsl_rng * r, const double p); +double gsl_ran_geometric_pdf (const unsigned int k, const double p); + +unsigned int gsl_ran_hypergeometric (const gsl_rng * r, unsigned int n1, unsigned int n2, unsigned int t); +double gsl_ran_hypergeometric_pdf (const unsigned int k, const unsigned int n1, const unsigned int n2, unsigned int t); + +double gsl_ran_gumbel1 (const gsl_rng * r, const double a, const double b); +double gsl_ran_gumbel1_pdf (const double x, const double a, const double b); + +double gsl_ran_gumbel2 (const gsl_rng * r, const double a, const double b); +double gsl_ran_gumbel2_pdf (const double x, const double a, const double b); + +double gsl_ran_logistic (const gsl_rng * r, const double a); +double gsl_ran_logistic_pdf (const double x, const double a); + +double gsl_ran_lognormal (const gsl_rng * r, const double zeta, const double sigma); +double gsl_ran_lognormal_pdf (const double x, const double zeta, const double sigma); + +unsigned int gsl_ran_logarithmic (const gsl_rng * r, const double p); +double gsl_ran_logarithmic_pdf (const unsigned int k, const double p); + +void gsl_ran_multinomial (const gsl_rng * r, const size_t K, + const unsigned int N, const double p[], + unsigned int n[] ); +double gsl_ran_multinomial_pdf (const size_t K, + const double p[], const unsigned int n[] ); +double gsl_ran_multinomial_lnpdf (const size_t K, + const double p[], const unsigned int n[] ); + + +unsigned int gsl_ran_negative_binomial (const gsl_rng * r, double p, double n); +double gsl_ran_negative_binomial_pdf (const unsigned int k, const double p, double n); + +unsigned int gsl_ran_pascal (const gsl_rng * r, double p, unsigned int n); +double gsl_ran_pascal_pdf (const unsigned int k, const double p, unsigned int n); + +double gsl_ran_pareto (const gsl_rng * r, double a, const double b); +double gsl_ran_pareto_pdf (const double x, const double a, const double b); + +unsigned int gsl_ran_poisson (const gsl_rng * r, double mu); +void gsl_ran_poisson_array (const gsl_rng * r, size_t n, unsigned int array[], + double mu); +double gsl_ran_poisson_pdf (const unsigned int k, const double mu); + +double gsl_ran_rayleigh (const gsl_rng * r, const double sigma); +double gsl_ran_rayleigh_pdf (const double x, const double sigma); + +double gsl_ran_rayleigh_tail (const gsl_rng * r, const double a, const double sigma); +double gsl_ran_rayleigh_tail_pdf (const double x, const double a, const double sigma); + +double gsl_ran_tdist (const gsl_rng * r, const double nu); +double gsl_ran_tdist_pdf (const double x, const double nu); + +double gsl_ran_laplace (const gsl_rng * r, const double a); +double gsl_ran_laplace_pdf (const double x, const double a); + +double gsl_ran_levy (const gsl_rng * r, const double c, const double alpha); +double gsl_ran_levy_skew (const gsl_rng * r, const double c, const double alpha, const double beta); + +double gsl_ran_weibull (const gsl_rng * r, const double a, const double b); +double gsl_ran_weibull_pdf (const double x, const double a, const double b); + +void gsl_ran_dir_2d (const gsl_rng * r, double * x, double * y); +void gsl_ran_dir_2d_trig_method (const gsl_rng * r, double * x, double * y); +void gsl_ran_dir_3d (const gsl_rng * r, double * x, double * y, double * z); +void gsl_ran_dir_nd (const gsl_rng * r, size_t n, double * x); + +void gsl_ran_shuffle (const gsl_rng * r, void * base, size_t nmembm, size_t size); +int gsl_ran_choose (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) ; +void gsl_ran_sample (const gsl_rng * r, void * dest, size_t k, void * src, size_t n, size_t size) ; + + +typedef struct { /* struct for Walker algorithm */ + size_t K; + size_t *A; + double *F; +} gsl_ran_discrete_t; + +gsl_ran_discrete_t * gsl_ran_discrete_preproc (size_t K, const double *P); +void gsl_ran_discrete_free(gsl_ran_discrete_t *g); +size_t gsl_ran_discrete (const gsl_rng *r, const gsl_ran_discrete_t *g); +double gsl_ran_discrete_pdf (size_t k, const gsl_ran_discrete_t *g); + + +__END_DECLS + +#endif /* __GSL_RANDIST_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_rng.h b/ChaosDataPlayer/GSL/include/gsl/gsl_rng.h new file mode 100644 index 0000000..4ec5591 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_rng.h @@ -0,0 +1,217 @@ +/* rng/gsl_rng.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004, 2007 James Theiler, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_RNG_H__ +#define __GSL_RNG_H__ +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct + { + const char *name; + unsigned long int max; + unsigned long int min; + size_t size; + void (*set) (void *state, unsigned long int seed); + unsigned long int (*get) (void *state); + double (*get_double) (void *state); + } +gsl_rng_type; + +typedef struct + { + const gsl_rng_type * type; + void *state; + } +gsl_rng; + + +/* These structs also need to appear in default.c so you can select + them via the environment variable GSL_RNG_TYPE */ + +GSL_VAR const gsl_rng_type *gsl_rng_borosh13; +GSL_VAR const gsl_rng_type *gsl_rng_coveyou; +GSL_VAR const gsl_rng_type *gsl_rng_cmrg; +GSL_VAR const gsl_rng_type *gsl_rng_fishman18; +GSL_VAR const gsl_rng_type *gsl_rng_fishman20; +GSL_VAR const gsl_rng_type *gsl_rng_fishman2x; +GSL_VAR const gsl_rng_type *gsl_rng_gfsr4; +GSL_VAR const gsl_rng_type *gsl_rng_knuthran; +GSL_VAR const gsl_rng_type *gsl_rng_knuthran2; +GSL_VAR const gsl_rng_type *gsl_rng_knuthran2002; +GSL_VAR const gsl_rng_type *gsl_rng_lecuyer21; +GSL_VAR const gsl_rng_type *gsl_rng_minstd; +GSL_VAR const gsl_rng_type *gsl_rng_mrg; +GSL_VAR const gsl_rng_type *gsl_rng_mt19937; +GSL_VAR const gsl_rng_type *gsl_rng_mt19937_1999; +GSL_VAR const gsl_rng_type *gsl_rng_mt19937_1998; +GSL_VAR const gsl_rng_type *gsl_rng_r250; +GSL_VAR const gsl_rng_type *gsl_rng_ran0; +GSL_VAR const gsl_rng_type *gsl_rng_ran1; +GSL_VAR const gsl_rng_type *gsl_rng_ran2; +GSL_VAR const gsl_rng_type *gsl_rng_ran3; +GSL_VAR const gsl_rng_type *gsl_rng_rand; +GSL_VAR const gsl_rng_type *gsl_rng_rand48; +GSL_VAR const gsl_rng_type *gsl_rng_random128_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random128_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random128_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_random256_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random256_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random256_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_random32_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random32_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random32_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_random64_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random64_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random64_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_random8_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random8_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random8_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_random_bsd; +GSL_VAR const gsl_rng_type *gsl_rng_random_glibc2; +GSL_VAR const gsl_rng_type *gsl_rng_random_libc5; +GSL_VAR const gsl_rng_type *gsl_rng_randu; +GSL_VAR const gsl_rng_type *gsl_rng_ranf; +GSL_VAR const gsl_rng_type *gsl_rng_ranlux; +GSL_VAR const gsl_rng_type *gsl_rng_ranlux389; +GSL_VAR const gsl_rng_type *gsl_rng_ranlxd1; +GSL_VAR const gsl_rng_type *gsl_rng_ranlxd2; +GSL_VAR const gsl_rng_type *gsl_rng_ranlxs0; +GSL_VAR const gsl_rng_type *gsl_rng_ranlxs1; +GSL_VAR const gsl_rng_type *gsl_rng_ranlxs2; +GSL_VAR const gsl_rng_type *gsl_rng_ranmar; +GSL_VAR const gsl_rng_type *gsl_rng_slatec; +GSL_VAR const gsl_rng_type *gsl_rng_taus; +GSL_VAR const gsl_rng_type *gsl_rng_taus2; +GSL_VAR const gsl_rng_type *gsl_rng_taus113; +GSL_VAR const gsl_rng_type *gsl_rng_transputer; +GSL_VAR const gsl_rng_type *gsl_rng_tt800; +GSL_VAR const gsl_rng_type *gsl_rng_uni; +GSL_VAR const gsl_rng_type *gsl_rng_uni32; +GSL_VAR const gsl_rng_type *gsl_rng_vax; +GSL_VAR const gsl_rng_type *gsl_rng_waterman14; +GSL_VAR const gsl_rng_type *gsl_rng_zuf; + +const gsl_rng_type ** gsl_rng_types_setup(void); + +GSL_VAR const gsl_rng_type *gsl_rng_default; +GSL_VAR unsigned long int gsl_rng_default_seed; + +gsl_rng *gsl_rng_alloc (const gsl_rng_type * T); +int gsl_rng_memcpy (gsl_rng * dest, const gsl_rng * src); +gsl_rng *gsl_rng_clone (const gsl_rng * r); + +void gsl_rng_free (gsl_rng * r); + +void gsl_rng_set (const gsl_rng * r, unsigned long int seed); +unsigned long int gsl_rng_max (const gsl_rng * r); +unsigned long int gsl_rng_min (const gsl_rng * r); +const char *gsl_rng_name (const gsl_rng * r); + +int gsl_rng_fread (FILE * stream, gsl_rng * r); +int gsl_rng_fwrite (FILE * stream, const gsl_rng * r); + +size_t gsl_rng_size (const gsl_rng * r); +void * gsl_rng_state (const gsl_rng * r); + +void gsl_rng_print_state (const gsl_rng * r); + +const gsl_rng_type * gsl_rng_env_setup (void); + +INLINE_DECL unsigned long int gsl_rng_get (const gsl_rng * r); +INLINE_DECL double gsl_rng_uniform (const gsl_rng * r); +INLINE_DECL double gsl_rng_uniform_pos (const gsl_rng * r); +INLINE_DECL unsigned long int gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n); + +#ifdef HAVE_INLINE + +INLINE_FUN unsigned long int +gsl_rng_get (const gsl_rng * r) +{ + return (r->type->get) (r->state); +} + +INLINE_FUN double +gsl_rng_uniform (const gsl_rng * r) +{ + return (r->type->get_double) (r->state); +} + +INLINE_FUN double +gsl_rng_uniform_pos (const gsl_rng * r) +{ + double x ; + do + { + x = (r->type->get_double) (r->state) ; + } + while (x == 0) ; + + return x ; +} + +/* Note: to avoid integer overflow in (range+1) we work with scale = + range/n = (max-min)/n rather than scale=(max-min+1)/n, this reduces + efficiency slightly but avoids having to check for the out of range + value. Note that range is typically O(2^32) so the addition of 1 + is negligible in most usage. */ + +INLINE_FUN unsigned long int +gsl_rng_uniform_int (const gsl_rng * r, unsigned long int n) +{ + unsigned long int offset = r->type->min; + unsigned long int range = r->type->max - offset; + unsigned long int scale; + unsigned long int k; + + if (n > range || n == 0) + { + GSL_ERROR_VAL ("invalid n, either 0 or exceeds maximum value of generator", + GSL_EINVAL, 0) ; + } + + scale = range / n; + + do + { + k = (((r->type->get) (r->state)) - offset) / scale; + } + while (k >= n); + + return k; +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_RNG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_roots.h b/ChaosDataPlayer/GSL/include/gsl/gsl_roots.h new file mode 100644 index 0000000..46e4587 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_roots.h @@ -0,0 +1,127 @@ +/* roots/gsl_roots.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Reid Priedhorsky, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_ROOTS_H__ +#define __GSL_ROOTS_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct + { + const char *name; + size_t size; + int (*set) (void *state, gsl_function * f, double * root, double x_lower, double x_upper); + int (*iterate) (void *state, gsl_function * f, double * root, double * x_lower, double * x_upper); + } +gsl_root_fsolver_type; + +typedef struct + { + const gsl_root_fsolver_type * type; + gsl_function * function ; + double root ; + double x_lower; + double x_upper; + void *state; + } +gsl_root_fsolver; + +typedef struct + { + const char *name; + size_t size; + int (*set) (void *state, gsl_function_fdf * f, double * root); + int (*iterate) (void *state, gsl_function_fdf * f, double * root); + } +gsl_root_fdfsolver_type; + +typedef struct + { + const gsl_root_fdfsolver_type * type; + gsl_function_fdf * fdf ; + double root ; + void *state; + } +gsl_root_fdfsolver; + +gsl_root_fsolver * +gsl_root_fsolver_alloc (const gsl_root_fsolver_type * T); +void gsl_root_fsolver_free (gsl_root_fsolver * s); + +int gsl_root_fsolver_set (gsl_root_fsolver * s, + gsl_function * f, + double x_lower, double x_upper); + +int gsl_root_fsolver_iterate (gsl_root_fsolver * s); + +const char * gsl_root_fsolver_name (const gsl_root_fsolver * s); +double gsl_root_fsolver_root (const gsl_root_fsolver * s); +double gsl_root_fsolver_x_lower (const gsl_root_fsolver * s); +double gsl_root_fsolver_x_upper (const gsl_root_fsolver * s); + + +gsl_root_fdfsolver * +gsl_root_fdfsolver_alloc (const gsl_root_fdfsolver_type * T); + +int +gsl_root_fdfsolver_set (gsl_root_fdfsolver * s, + gsl_function_fdf * fdf, double root); + +int +gsl_root_fdfsolver_iterate (gsl_root_fdfsolver * s); + +void +gsl_root_fdfsolver_free (gsl_root_fdfsolver * s); + +const char * gsl_root_fdfsolver_name (const gsl_root_fdfsolver * s); +double gsl_root_fdfsolver_root (const gsl_root_fdfsolver * s); + +int +gsl_root_test_interval (double x_lower, double x_upper, double epsabs, double epsrel); + +int +gsl_root_test_residual (double f, double epsabs); + +int +gsl_root_test_delta (double x1, double x0, double epsabs, double epsrel); + +GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_bisection; +GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_brent; +GSL_VAR const gsl_root_fsolver_type * gsl_root_fsolver_falsepos; +GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_newton; +GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_secant; +GSL_VAR const gsl_root_fdfsolver_type * gsl_root_fdfsolver_steffenson; + +__END_DECLS + +#endif /* __GSL_ROOTS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_rstat.h b/ChaosDataPlayer/GSL/include/gsl/gsl_rstat.h new file mode 100644 index 0000000..0013a2a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_rstat.h @@ -0,0 +1,83 @@ +/* rstat/gsl_rstat.h + * + * Copyright (C) 2015 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_RSTAT_H__ +#define __GSL_RSTAT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + double p; /* p-quantile */ + double q[5]; /* heights q_i */ + int npos[5]; /* positions n_i */ + double np[5]; /* desired positions n_i' */ + double dnp[5]; /* increments dn_i' */ + size_t n; /* number of data added */ +} gsl_rstat_quantile_workspace; + +gsl_rstat_quantile_workspace *gsl_rstat_quantile_alloc(const double p); +void gsl_rstat_quantile_free(gsl_rstat_quantile_workspace *w); +int gsl_rstat_quantile_reset(gsl_rstat_quantile_workspace *w); +int gsl_rstat_quantile_add(const double x, gsl_rstat_quantile_workspace *w); +double gsl_rstat_quantile_get(gsl_rstat_quantile_workspace *w); + +typedef struct +{ + double min; /* minimum value added */ + double max; /* maximum value added */ + double mean; /* current mean */ + double M2; /* M_k = sum_{i=1..n} [ x_i - mean_n ]^k */ + double M3; + double M4; + size_t n; /* number of data points added */ + gsl_rstat_quantile_workspace *median_workspace_p; /* median workspace */ +} gsl_rstat_workspace; + +gsl_rstat_workspace *gsl_rstat_alloc(void); +void gsl_rstat_free(gsl_rstat_workspace *w); +size_t gsl_rstat_n(const gsl_rstat_workspace *w); +int gsl_rstat_add(const double x, gsl_rstat_workspace *w); +double gsl_rstat_min(const gsl_rstat_workspace *w); +double gsl_rstat_max(const gsl_rstat_workspace *w); +double gsl_rstat_mean(const gsl_rstat_workspace *w); +double gsl_rstat_variance(const gsl_rstat_workspace *w); +double gsl_rstat_sd(const gsl_rstat_workspace *w); +double gsl_rstat_rms(const gsl_rstat_workspace *w); +double gsl_rstat_sd_mean(const gsl_rstat_workspace *w); +double gsl_rstat_median(gsl_rstat_workspace *w); +double gsl_rstat_skew(const gsl_rstat_workspace *w); +double gsl_rstat_kurtosis(const gsl_rstat_workspace *w); +int gsl_rstat_reset(gsl_rstat_workspace *w); + +__END_DECLS + +#endif /* __GSL_RSTAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf.h new file mode 100644 index 0000000..cb9cafd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf.h @@ -0,0 +1,41 @@ +/* Author: G. Jungman */ + +#ifndef __GSL_SF_H__ +#define __GSL_SF_H__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif /* __GSL_SF_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_airy.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_airy.h new file mode 100644 index 0000000..7033383 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_airy.h @@ -0,0 +1,139 @@ +/* specfunc/gsl_sf_airy.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_AIRY_H__ +#define __GSL_SF_AIRY_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Airy function Ai(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_airy_Ai_e(const double x, const gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Ai(const double x, gsl_mode_t mode); + + +/* Airy function Bi(x) + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_airy_Bi_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Bi(const double x, gsl_mode_t mode); + + +/* scaled Ai(x): + * Ai(x) x < 0 + * exp(+2/3 x^{3/2}) Ai(x) x > 0 + * + * exceptions: none + */ +int gsl_sf_airy_Ai_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Ai_scaled(const double x, gsl_mode_t mode); + + +/* scaled Bi(x): + * Bi(x) x < 0 + * exp(-2/3 x^{3/2}) Bi(x) x > 0 + * + * exceptions: none + */ +int gsl_sf_airy_Bi_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Bi_scaled(const double x, gsl_mode_t mode); + + +/* derivative Ai'(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_airy_Ai_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Ai_deriv(const double x, gsl_mode_t mode); + + +/* derivative Bi'(x) + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_airy_Bi_deriv_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Bi_deriv(const double x, gsl_mode_t mode); + + +/* scaled derivative Ai'(x): + * Ai'(x) x < 0 + * exp(+2/3 x^{3/2}) Ai'(x) x > 0 + * + * exceptions: none + */ +int gsl_sf_airy_Ai_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Ai_deriv_scaled(const double x, gsl_mode_t mode); + + +/* scaled derivative: + * Bi'(x) x < 0 + * exp(-2/3 x^{3/2}) Bi'(x) x > 0 + * + * exceptions: none + */ +int gsl_sf_airy_Bi_deriv_scaled_e(const double x, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_airy_Bi_deriv_scaled(const double x, gsl_mode_t mode); + + +/* Zeros of Ai(x) + */ +int gsl_sf_airy_zero_Ai_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_airy_zero_Ai(unsigned int s); + + +/* Zeros of Bi(x) + */ +int gsl_sf_airy_zero_Bi_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_airy_zero_Bi(unsigned int s); + + +/* Zeros of Ai'(x) + */ +int gsl_sf_airy_zero_Ai_deriv_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_airy_zero_Ai_deriv(unsigned int s); + + +/* Zeros of Bi'(x) + */ +int gsl_sf_airy_zero_Bi_deriv_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_airy_zero_Bi_deriv(unsigned int s); + + +__END_DECLS + +#endif /* __GSL_SF_AIRY_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_bessel.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_bessel.h new file mode 100644 index 0000000..d72957a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_bessel.h @@ -0,0 +1,549 @@ +/* specfunc/gsl_sf_bessel.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_BESSEL_H__ +#define __GSL_SF_BESSEL_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Regular Bessel Function J_0(x) + * + * exceptions: none + */ +int gsl_sf_bessel_J0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_J0(const double x); + + +/* Regular Bessel Function J_1(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_J1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_J1(const double x); + + +/* Regular Bessel Function J_n(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_Jn_e(int n, double x, gsl_sf_result * result); +double gsl_sf_bessel_Jn(const int n, const double x); + + +/* Regular Bessel Function J_n(x), nmin <= n <= nmax + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Jn_array(int nmin, int nmax, double x, double * result_array); + + +/* Irregular Bessel function Y_0(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Y0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_Y0(const double x); + + +/* Irregular Bessel function Y_1(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Y1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_Y1(const double x); + + +/* Irregular Bessel function Y_n(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Yn_e(int n,const double x, gsl_sf_result * result); +double gsl_sf_bessel_Yn(const int n,const double x); + + +/* Irregular Bessel function Y_n(x), nmin <= n <= nmax + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Yn_array(const int nmin, const int nmax, const double x, double * result_array); + + +/* Regular modified Bessel function I_0(x) + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_bessel_I0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_I0(const double x); + + +/* Regular modified Bessel function I_1(x) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_I1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_I1(const double x); + + +/* Regular modified Bessel function I_n(x) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_In_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_bessel_In(const int n, const double x); + + +/* Regular modified Bessel function I_n(x) for n=nmin,...,nmax + * + * nmin >=0, nmax >= nmin + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_In_array(const int nmin, const int nmax, const double x, double * result_array); + + +/* Scaled regular modified Bessel function + * exp(-|x|) I_0(x) + * + * exceptions: none + */ +int gsl_sf_bessel_I0_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_I0_scaled(const double x); + + +/* Scaled regular modified Bessel function + * exp(-|x|) I_1(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_I1_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_I1_scaled(const double x); + + +/* Scaled regular modified Bessel function + * exp(-|x|) I_n(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_In_scaled_e(int n, const double x, gsl_sf_result * result); +double gsl_sf_bessel_In_scaled(const int n, const double x); + + +/* Scaled regular modified Bessel function + * exp(-|x|) I_n(x) for n=nmin,...,nmax + * + * nmin >=0, nmax >= nmin + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_In_scaled_array(const int nmin, const int nmax, const double x, double * result_array); + + +/* Irregular modified Bessel function K_0(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_K0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_K0(const double x); + + +/* Irregular modified Bessel function K_1(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_K1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_K1(const double x); + + +/* Irregular modified Bessel function K_n(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Kn_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_bessel_Kn(const int n, const double x); + + +/* Irregular modified Bessel function K_n(x) for n=nmin,...,nmax + * + * x > 0.0, nmin >=0, nmax >= nmin + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Kn_array(const int nmin, const int nmax, const double x, double * result_array); + + +/* Scaled irregular modified Bessel function + * exp(x) K_0(x) + * + * x > 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_bessel_K0_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_K0_scaled(const double x); + + +/* Scaled irregular modified Bessel function + * exp(x) K_1(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_K1_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_K1_scaled(const double x); + + +/* Scaled irregular modified Bessel function + * exp(x) K_n(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Kn_scaled_e(int n, const double x, gsl_sf_result * result); +double gsl_sf_bessel_Kn_scaled(const int n, const double x); + + +/* Scaled irregular modified Bessel function exp(x) K_n(x) for n=nmin,...,nmax + * + * x > 0.0, nmin >=0, nmax >= nmin + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Kn_scaled_array(const int nmin, const int nmax, const double x, double * result_array); + + +/* Regular spherical Bessel function j_0(x) = sin(x)/x + * + * exceptions: none + */ +int gsl_sf_bessel_j0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_j0(const double x); + + +/* Regular spherical Bessel function j_1(x) = (sin(x)/x - cos(x))/x + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_j1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_j1(const double x); + + +/* Regular spherical Bessel function j_2(x) = ((3/x^2 - 1)sin(x) - 3cos(x)/x)/x + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_j2_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_j2(const double x); + + +/* Regular spherical Bessel function j_l(x) + * + * l >= 0, x >= 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_jl_e(const int l, const double x, gsl_sf_result * result); +double gsl_sf_bessel_jl(const int l, const double x); + + +/* Regular spherical Bessel function j_l(x) for l=0,1,...,lmax + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_jl_array(const int lmax, const double x, double * result_array); + + +/* Regular spherical Bessel function j_l(x) for l=0,1,...,lmax + * Uses Steed's method. + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_jl_steed_array(const int lmax, const double x, double * jl_x_array); + + +/* Irregular spherical Bessel function y_0(x) + * + * exceptions: none + */ +int gsl_sf_bessel_y0_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_y0(const double x); + + +/* Irregular spherical Bessel function y_1(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_y1_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_y1(const double x); + + +/* Irregular spherical Bessel function y_2(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_y2_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_y2(const double x); + + +/* Irregular spherical Bessel function y_l(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_yl_e(int l, const double x, gsl_sf_result * result); +double gsl_sf_bessel_yl(const int l, const double x); + + +/* Irregular spherical Bessel function y_l(x) for l=0,1,...,lmax + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_yl_array(const int lmax, const double x, double * result_array); + + +/* Regular scaled modified spherical Bessel function + * + * Exp[-|x|] i_0(x) + * + * exceptions: none + */ +int gsl_sf_bessel_i0_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_i0_scaled(const double x); + + +/* Regular scaled modified spherical Bessel function + * + * Exp[-|x|] i_1(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_i1_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_i1_scaled(const double x); + + +/* Regular scaled modified spherical Bessel function + * + * Exp[-|x|] i_2(x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_i2_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_i2_scaled(const double x); + + +/* Regular scaled modified spherical Bessel functions + * + * Exp[-|x|] i_l(x) + * + * i_l(x) = Sqrt[Pi/(2x)] BesselI[l+1/2,x] + * + * l >= 0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_il_scaled_e(const int l, double x, gsl_sf_result * result); +double gsl_sf_bessel_il_scaled(const int l, const double x); + + +/* Regular scaled modified spherical Bessel functions + * + * Exp[-|x|] i_l(x) + * for l=0,1,...,lmax + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_bessel_il_scaled_array(const int lmax, const double x, double * result_array); + + +/* Irregular scaled modified spherical Bessel function + * Exp[x] k_0(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_k0_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_k0_scaled(const double x); + + +/* Irregular modified spherical Bessel function + * Exp[x] k_1(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_bessel_k1_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_k1_scaled(const double x); + + +/* Irregular modified spherical Bessel function + * Exp[x] k_2(x) + * + * x > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_bessel_k2_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_bessel_k2_scaled(const double x); + + +/* Irregular modified spherical Bessel function + * Exp[x] k_l[x] + * + * k_l(x) = Sqrt[Pi/(2x)] BesselK[l+1/2,x] + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_kl_scaled_e(int l, const double x, gsl_sf_result * result); +double gsl_sf_bessel_kl_scaled(const int l, const double x); + + +/* Irregular scaled modified spherical Bessel function + * Exp[x] k_l(x) + * + * for l=0,1,...,lmax + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_kl_scaled_array(const int lmax, const double x, double * result_array); + + +/* Regular cylindrical Bessel function J_nu(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Jnu_e(const double nu, const double x, gsl_sf_result * result); +double gsl_sf_bessel_Jnu(const double nu, const double x); + + +/* Irregular cylindrical Bessel function Y_nu(x) + * + * exceptions: + */ +int gsl_sf_bessel_Ynu_e(double nu, double x, gsl_sf_result * result); +double gsl_sf_bessel_Ynu(const double nu, const double x); + + +/* Regular cylindrical Bessel function J_nu(x) + * evaluated at a series of x values. The array + * contains the x values. They are assumed to be + * strictly ordered and positive. The array is + * over-written with the values of J_nu(x_i). + * + * exceptions: GSL_EDOM, GSL_EINVAL + */ +int gsl_sf_bessel_sequence_Jnu_e(double nu, gsl_mode_t mode, size_t size, double * v); + + +/* Scaled modified cylindrical Bessel functions + * + * Exp[-|x|] BesselI[nu, x] + * x >= 0, nu >= 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_bessel_Inu_scaled_e(double nu, double x, gsl_sf_result * result); +double gsl_sf_bessel_Inu_scaled(double nu, double x); + + +/* Modified cylindrical Bessel functions + * + * BesselI[nu, x] + * x >= 0, nu >= 0 + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_bessel_Inu_e(double nu, double x, gsl_sf_result * result); +double gsl_sf_bessel_Inu(double nu, double x); + + +/* Scaled modified cylindrical Bessel functions + * + * Exp[+|x|] BesselK[nu, x] + * x > 0, nu >= 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_bessel_Knu_scaled_e(const double nu, const double x, gsl_sf_result * result); +double gsl_sf_bessel_Knu_scaled(const double nu, const double x); + +int gsl_sf_bessel_Knu_scaled_e10_e(const double nu, const double x, gsl_sf_result_e10 * result); + +/* Modified cylindrical Bessel functions + * + * BesselK[nu, x] + * x > 0, nu >= 0 + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_bessel_Knu_e(const double nu, const double x, gsl_sf_result * result); +double gsl_sf_bessel_Knu(const double nu, const double x); + + +/* Logarithm of modified cylindrical Bessel functions. + * + * Log[BesselK[nu, x]] + * x > 0, nu >= 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_bessel_lnKnu_e(const double nu, const double x, gsl_sf_result * result); +double gsl_sf_bessel_lnKnu(const double nu, const double x); + + +/* s'th positive zero of the Bessel function J_0(x). + * + * exceptions: + */ +int gsl_sf_bessel_zero_J0_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_bessel_zero_J0(unsigned int s); + + +/* s'th positive zero of the Bessel function J_1(x). + * + * exceptions: + */ +int gsl_sf_bessel_zero_J1_e(unsigned int s, gsl_sf_result * result); +double gsl_sf_bessel_zero_J1(unsigned int s); + + +/* s'th positive zero of the Bessel function J_nu(x). + * + * exceptions: + */ +int gsl_sf_bessel_zero_Jnu_e(double nu, unsigned int s, gsl_sf_result * result); +double gsl_sf_bessel_zero_Jnu(double nu, unsigned int s); + + +__END_DECLS + +#endif /* __GSL_SF_BESSEL_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_clausen.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_clausen.h new file mode 100644 index 0000000..8e4ccd2 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_clausen.h @@ -0,0 +1,52 @@ +/* specfunc/gsl_sf_clausen.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_CLAUSEN_H__ +#define __GSL_SF_CLAUSEN_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Calculate the Clausen integral: + * Cl_2(x) := Integrate[-Log[2 Sin[t/2]], {t,0,x}] + * + * Relation to dilogarithm: + * Cl_2(theta) = Im[ Li_2(e^(i theta)) ] + */ +int gsl_sf_clausen_e(double x, gsl_sf_result * result); +double gsl_sf_clausen(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_CLAUSEN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coulomb.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coulomb.h new file mode 100644 index 0000000..764a571 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coulomb.h @@ -0,0 +1,128 @@ +/* specfunc/gsl_sf_coulomb.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_COULOMB_H__ +#define __GSL_SF_COULOMB_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Normalized hydrogenic bound states, radial dependence. */ + +/* R_1 := 2Z sqrt(Z) exp(-Z r) + */ +int gsl_sf_hydrogenicR_1_e(const double Z, const double r, gsl_sf_result * result); +double gsl_sf_hydrogenicR_1(const double Z, const double r); + +/* R_n := norm exp(-Z r/n) (2Z/n)^l Laguerre[n-l-1, 2l+1, 2Z/n r] + * + * normalization such that psi(n,l,r) = R_n Y_{lm} + */ +int gsl_sf_hydrogenicR_e(const int n, const int l, const double Z, const double r, gsl_sf_result * result); +double gsl_sf_hydrogenicR(const int n, const int l, const double Z, const double r); + + +/* Coulomb wave functions F_{lam_F}(eta,x), G_{lam_G}(eta,x) + * and their derivatives; lam_G := lam_F - k_lam_G + * + * lam_F, lam_G > -0.5 + * x > 0.0 + * + * Conventions of Abramowitz+Stegun. + * + * Because there can be a large dynamic range of values, + * overflows are handled gracefully. If an overflow occurs, + * GSL_EOVRFLW is signalled and exponent(s) are returned + * through exp_F, exp_G. These are such that + * + * F_L(eta,x) = fc[k_L] * exp(exp_F) + * G_L(eta,x) = gc[k_L] * exp(exp_G) + * F_L'(eta,x) = fcp[k_L] * exp(exp_F) + * G_L'(eta,x) = gcp[k_L] * exp(exp_G) + */ +int +gsl_sf_coulomb_wave_FG_e(const double eta, const double x, + const double lam_F, + const int k_lam_G, + gsl_sf_result * F, gsl_sf_result * Fp, + gsl_sf_result * G, gsl_sf_result * Gp, + double * exp_F, double * exp_G); + + +/* F_L(eta,x) as array */ +int gsl_sf_coulomb_wave_F_array( + double lam_min, int kmax, + double eta, double x, + double * fc_array, + double * F_exponent + ); + +/* F_L(eta,x), G_L(eta,x) as arrays */ +int gsl_sf_coulomb_wave_FG_array(double lam_min, int kmax, + double eta, double x, + double * fc_array, double * gc_array, + double * F_exponent, + double * G_exponent + ); + +/* F_L(eta,x), G_L(eta,x), F'_L(eta,x), G'_L(eta,x) as arrays */ +int gsl_sf_coulomb_wave_FGp_array(double lam_min, int kmax, + double eta, double x, + double * fc_array, double * fcp_array, + double * gc_array, double * gcp_array, + double * F_exponent, + double * G_exponent + ); + +/* Coulomb wave function divided by the argument, + * F(eta, x)/x. This is the function which reduces to + * spherical Bessel functions in the limit eta->0. + */ +int gsl_sf_coulomb_wave_sphF_array(double lam_min, int kmax, + double eta, double x, + double * fc_array, + double * F_exponent + ); + + +/* Coulomb wave function normalization constant. + * [Abramowitz+Stegun 14.1.8, 14.1.9] + */ +int gsl_sf_coulomb_CL_e(double L, double eta, gsl_sf_result * result); +int gsl_sf_coulomb_CL_array(double Lmin, int kmax, double eta, double * cl); + + +__END_DECLS + +#endif /* __GSL_SF_COULOMB_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coupling.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coupling.h new file mode 100644 index 0000000..c46b9f5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_coupling.h @@ -0,0 +1,125 @@ +/* specfunc/gsl_sf_coupling.h + * + * Copyright (C) 1996,1997,1998,1999,2000,2001,2002 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_COUPLING_H__ +#define __GSL_SF_COUPLING_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* 3j Symbols: / ja jb jc \ + * \ ma mb mc / + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_coupling_3j_e(int two_ja, int two_jb, int two_jc, + int two_ma, int two_mb, int two_mc, + gsl_sf_result * result + ); +double gsl_sf_coupling_3j(int two_ja, int two_jb, int two_jc, + int two_ma, int two_mb, int two_mc + ); + + +/* 6j Symbols: / ja jb jc \ + * \ jd je jf / + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_coupling_6j_e(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf, + gsl_sf_result * result + ); +double gsl_sf_coupling_6j(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf + ); + +/* Racah W coefficients: + * + * W(a b c d; e f) = (-1)^{a+b+c+d} / a b e \ + * \ d c f / + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_coupling_RacahW_e(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf, + gsl_sf_result * result + ); +double gsl_sf_coupling_RacahW(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf + ); + + +/* 9j Symbols: / ja jb jc \ + * | jd je jf | + * \ jg jh ji / + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_coupling_9j_e(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf, + int two_jg, int two_jh, int two_ji, + gsl_sf_result * result + ); +double gsl_sf_coupling_9j(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf, + int two_jg, int two_jh, int two_ji + ); + + +/* INCORRECT version of 6j Symbols: + * This function actually calculates + * / ja jb je \ + * \ jd jc jf / + * It represents the original implementation, + * which had the above permutation of the + * arguments. This was wrong and confusing, + * and I had to fix it. Sorry for the trouble. + * [GJ] Tue Nov 26 12:53:39 MST 2002 + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +#ifndef GSL_DISABLE_DEPRECATED +int gsl_sf_coupling_6j_INCORRECT_e(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf, + gsl_sf_result * result + ); +double gsl_sf_coupling_6j_INCORRECT(int two_ja, int two_jb, int two_jc, + int two_jd, int two_je, int two_jf + ); +#endif /* !GSL_DISABLE_DEPRECATED */ + + +__END_DECLS + +#endif /* __GSL_SF_COUPLING_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dawson.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dawson.h new file mode 100644 index 0000000..7c11f9f --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dawson.h @@ -0,0 +1,52 @@ +/* specfunc/gsl_sf_dawson.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_DAWSON_H__ +#define __GSL_SF_DAWSON_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Dawson's integral: + * + * Exp[-x^2] Integral[ Exp[t^2], {t,0,x}] + * + * exceptions: GSL_EUNDRFLW; + */ +int gsl_sf_dawson_e(double x, gsl_sf_result * result); +double gsl_sf_dawson(double x); + + +__END_DECLS + +#endif /* __GSL_SF_DAWSON_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_debye.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_debye.h new file mode 100644 index 0000000..bc732b1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_debye.h @@ -0,0 +1,91 @@ +/* specfunc/gsl_sf_debye.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ +/* augmented by D_5(x) and D_6(x) by Richard J. Mathar, 2005-11-08 */ + +#ifndef __GSL_SF_DEBYE_H__ +#define __GSL_SF_DEBYE_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* D_n(x) := n/x^n Integrate[t^n/(e^t - 1), {t,0,x}] */ + +/* D_1(x) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_debye_1_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_1(const double x); + + +/* D_2(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_debye_2_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_2(const double x); + + +/* D_3(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_debye_3_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_3(const double x); + + +/* D_4(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_debye_4_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_4(const double x); + +/* D_5(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_debye_5_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_5(const double x); + +/* D_6(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_debye_6_e(const double x, gsl_sf_result * result); +double gsl_sf_debye_6(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_DEBYE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dilog.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dilog.h new file mode 100644 index 0000000..79b2b76 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_dilog.h @@ -0,0 +1,130 @@ +/* specfunc/gsl_sf_dilog.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_DILOG_H__ +#define __GSL_SF_DILOG_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Real part of DiLogarithm(x), for real argument. + * In Lewin's notation, this is Li_2(x). + * + * Li_2(x) = - Re[ Integrate[ Log[1-s] / s, {s, 0, x}] ] + * + * The function in the complex plane has a branch point + * at z = 1; we place the cut in the conventional way, + * on [1, +infty). This means that the value for real x > 1 + * is a matter of definition; however, this choice does not + * affect the real part and so is not relevant to the + * interpretation of this implemented function. + */ +int gsl_sf_dilog_e(const double x, gsl_sf_result * result); +double gsl_sf_dilog(const double x); + + +/* DiLogarithm(z), for complex argument z = x + i y. + * Computes the principal branch. + * + * Recall that the branch cut is on the real axis with x > 1. + * The imaginary part of the computed value on the cut is given + * by -Pi*log(x), which is the limiting value taken approaching + * from y < 0. This is a conventional choice, though there is no + * true standardized choice. + * + * Note that there is no canonical way to lift the defining + * contour to the full Riemann surface because of the appearance + * of a "hidden branch point" at z = 0 on non-principal sheets. + * Experts will know the simple algebraic prescription for + * obtaining the sheet they want; non-experts will not want + * to know anything about it. This is why GSL chooses to compute + * only on the principal branch. + */ +int +gsl_sf_complex_dilog_xy_e( + const double x, + const double y, + gsl_sf_result * result_re, + gsl_sf_result * result_im + ); + + + +/* DiLogarithm(z), for complex argument z = r Exp[i theta]. + * Computes the principal branch, thereby assuming an + * implicit reduction of theta to the range (-2 pi, 2 pi). + * + * If theta is identically zero, the imaginary part is computed + * as if approaching from y > 0. For other values of theta no + * special consideration is given, since it is assumed that + * no other machine representations of multiples of pi will + * produce y = 0 precisely. This assumption depends on some + * subtle properties of the machine arithmetic, such as + * correct rounding and monotonicity of the underlying + * implementation of sin() and cos(). + * + * This function is ok, but the interface is confusing since + * it makes it appear that the branch structure is resolved. + * Furthermore the handling of values close to the branch + * cut is subtle. Perhap this interface should be deprecated. + */ +int +gsl_sf_complex_dilog_e( + const double r, + const double theta, + gsl_sf_result * result_re, + gsl_sf_result * result_im + ); + + + +/* Spence integral; spence(s) := Li_2(1-s) + * + * This function has a branch point at 0; we place the + * cut on (-infty,0). Because of our choice for the value + * of Li_2(z) on the cut, spence(s) is continuous as + * s approaches the cut from above. In other words, + * we define spence(x) = spence(x + i 0+). + */ +int +gsl_sf_complex_spence_xy_e( + const double x, + const double y, + gsl_sf_result * real_sp, + gsl_sf_result * imag_sp + ); + + +__END_DECLS + +#endif /* __GSL_SF_DILOG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elementary.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elementary.h new file mode 100644 index 0000000..467bfda --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elementary.h @@ -0,0 +1,57 @@ +/* specfunc/gsl_sf_elementary.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +/* Miscellaneous elementary functions and operations. + */ +#ifndef __GSL_SF_ELEMENTARY_H__ +#define __GSL_SF_ELEMENTARY_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Multiplication. + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_multiply_e(const double x, const double y, gsl_sf_result * result); +double gsl_sf_multiply(const double x, const double y); + + +/* Multiplication of quantities with associated errors. + */ +int gsl_sf_multiply_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result); + + +__END_DECLS + +#endif /* __GSL_SF_ELEMENTARY_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_ellint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_ellint.h new file mode 100644 index 0000000..7f68f0e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_ellint.h @@ -0,0 +1,112 @@ +/* specfunc/gsl_sf_ellint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_ELLINT_H__ +#define __GSL_SF_ELLINT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Legendre form of complete elliptic integrals + * + * K(k) = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}] + * E(k) = Integral[ Sqrt[1 - k^2 Sin[t]^2], {t, 0, Pi/2}] + * + * exceptions: GSL_EDOM + */ +int gsl_sf_ellint_Kcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_Kcomp(double k, gsl_mode_t mode); + +int gsl_sf_ellint_Ecomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_Ecomp(double k, gsl_mode_t mode); + +int gsl_sf_ellint_Pcomp_e(double k, double n, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_Pcomp(double k, double n, gsl_mode_t mode); + +int gsl_sf_ellint_Dcomp_e(double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_Dcomp(double k, gsl_mode_t mode); + + +/* Legendre form of incomplete elliptic integrals + * + * F(phi,k) = Integral[1/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] + * E(phi,k) = Integral[ Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] + * P(phi,k,n) = Integral[(1 + n Sin[t]^2)^(-1)/Sqrt[1 - k^2 Sin[t]^2], {t, 0, phi}] + * D(phi,k,n) = R_D(1-Sin[phi]^2, 1-k^2 Sin[phi]^2, 1.0) + * + * F: [Carlson, Numerische Mathematik 33 (1979) 1, (4.1)] + * E: [Carlson, ", (4.2)] + * P: [Carlson, ", (4.3)] + * D: [Carlson, ", (4.4)] + * + * exceptions: GSL_EDOM + */ +int gsl_sf_ellint_F_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_F(double phi, double k, gsl_mode_t mode); + +int gsl_sf_ellint_E_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_E(double phi, double k, gsl_mode_t mode); + +int gsl_sf_ellint_P_e(double phi, double k, double n, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_P(double phi, double k, double n, gsl_mode_t mode); + +int gsl_sf_ellint_D_e(double phi, double k, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_D(double phi, double k, gsl_mode_t mode); + + +/* Carlson's symmetric basis of functions + * + * RC(x,y) = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1)], {t,0,Inf}] + * RD(x,y,z) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-3/2), {t,0,Inf}] + * RF(x,y,z) = 1/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2), {t,0,Inf}] + * RJ(x,y,z,p) = 3/2 Integral[(t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1), {t,0,Inf}] + * + * exceptions: GSL_EDOM + */ +int gsl_sf_ellint_RC_e(double x, double y, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_RC(double x, double y, gsl_mode_t mode); + +int gsl_sf_ellint_RD_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_RD(double x, double y, double z, gsl_mode_t mode); + +int gsl_sf_ellint_RF_e(double x, double y, double z, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_RF(double x, double y, double z, gsl_mode_t mode); + +int gsl_sf_ellint_RJ_e(double x, double y, double z, double p, gsl_mode_t mode, gsl_sf_result * result); +double gsl_sf_ellint_RJ(double x, double y, double z, double p, gsl_mode_t mode); + + +__END_DECLS + +#endif /* __GSL_SF_ELLINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elljac.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elljac.h new file mode 100644 index 0000000..7f804a5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_elljac.h @@ -0,0 +1,48 @@ +/* specfunc/gsl_sf_elljac.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_ELLJAC_H__ +#define __GSL_SF_ELLJAC_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Jacobian elliptic functions sn, dn, cn, + * by descending Landen transformations + * + * exceptions: GSL_EDOM + */ +int gsl_sf_elljac_e(double u, double m, double * sn, double * cn, double * dn); + + +__END_DECLS + +#endif /* __GSL_SF_ELLJAC_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_erf.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_erf.h new file mode 100644 index 0000000..a196d0d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_erf.h @@ -0,0 +1,91 @@ +/* specfunc/gsl_sf_erf.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_ERF_H__ +#define __GSL_SF_ERF_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Complementary Error Function + * erfc(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,x,Infinity}] + * + * exceptions: none + */ +int gsl_sf_erfc_e(double x, gsl_sf_result * result); +double gsl_sf_erfc(double x); + + +/* Log Complementary Error Function + * + * exceptions: none + */ +int gsl_sf_log_erfc_e(double x, gsl_sf_result * result); +double gsl_sf_log_erfc(double x); + + +/* Error Function + * erf(x) := 2/Sqrt[Pi] Integrate[Exp[-t^2], {t,0,x}] + * + * exceptions: none + */ +int gsl_sf_erf_e(double x, gsl_sf_result * result); +double gsl_sf_erf(double x); + + +/* Probability functions: + * Z(x) : Abramowitz+Stegun 26.2.1 + * Q(x) : Abramowitz+Stegun 26.2.3 + * + * exceptions: none + */ +int gsl_sf_erf_Z_e(double x, gsl_sf_result * result); +int gsl_sf_erf_Q_e(double x, gsl_sf_result * result); +double gsl_sf_erf_Z(double x); +double gsl_sf_erf_Q(double x); + + +/* Hazard function, also known as the inverse Mill's ratio. + * + * H(x) := Z(x)/Q(x) + * = Sqrt[2/Pi] Exp[-x^2 / 2] / Erfc[x/Sqrt[2]] + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_hazard_e(double x, gsl_sf_result * result); +double gsl_sf_hazard(double x); + + +__END_DECLS + +#endif /* __GSL_SF_ERF_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_exp.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_exp.h new file mode 100644 index 0000000..8f8aff7 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_exp.h @@ -0,0 +1,134 @@ +/* specfunc/gsl_sf_exp.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_EXP_H__ +#define __GSL_SF_EXP_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Provide an exp() function with GSL semantics, + * i.e. with proper error checking, etc. + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_e(const double x, gsl_sf_result * result); +double gsl_sf_exp(const double x); + + +/* Exp(x) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_e10_e(const double x, gsl_sf_result_e10 * result); + + +/* Exponentiate and multiply by a given factor: y * Exp(x) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_mult_e(const double x, const double y, gsl_sf_result * result); +double gsl_sf_exp_mult(const double x, const double y); + + +/* Exponentiate and multiply by a given factor: y * Exp(x) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_mult_e10_e(const double x, const double y, gsl_sf_result_e10 * result); + + +/* exp(x)-1 + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_expm1_e(const double x, gsl_sf_result * result); +double gsl_sf_expm1(const double x); + + +/* (exp(x)-1)/x = 1 + x/2 + x^2/(2*3) + x^3/(2*3*4) + ... + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_exprel_e(const double x, gsl_sf_result * result); +double gsl_sf_exprel(const double x); + + +/* 2(exp(x)-1-x)/x^2 = 1 + x/3 + x^2/(3*4) + x^3/(3*4*5) + ... + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_exprel_2_e(double x, gsl_sf_result * result); +double gsl_sf_exprel_2(const double x); + + +/* Similarly for the N-th generalization of + * the above. The so-called N-relative exponential + * + * exprel_N(x) = N!/x^N (exp(x) - Sum[x^k/k!, {k,0,N-1}]) + * = 1 + x/(N+1) + x^2/((N+1)(N+2)) + ... + * = 1F1(1,1+N,x) + */ +int gsl_sf_exprel_n_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_exprel_n(const int n, const double x); + +int gsl_sf_exprel_n_CF_e(const double n, const double x, gsl_sf_result * result); + + +/* Exponentiate a quantity with an associated error. + */ +int gsl_sf_exp_err_e(const double x, const double dx, gsl_sf_result * result); + +/* Exponentiate a quantity with an associated error. + */ +int gsl_sf_exp_err_e10_e(const double x, const double dx, gsl_sf_result_e10 * result); + + +/* Exponentiate and multiply by a given factor: y * Exp(x), + * for quantities with associated errors. + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_mult_err_e(const double x, const double dx, const double y, const double dy, gsl_sf_result * result); + + +/* Exponentiate and multiply by a given factor: y * Exp(x), + * for quantities with associated errors. + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_exp_mult_err_e10_e(const double x, const double dx, const double y, const double dy, gsl_sf_result_e10 * result); + +__END_DECLS + +#endif /* __GSL_SF_EXP_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_expint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_expint.h new file mode 100644 index 0000000..4005f72 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_expint.h @@ -0,0 +1,167 @@ +/* specfunc/gsl_sf_expint.h + * + * Copyright (C) 2007 Brian Gough + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_EXPINT_H__ +#define __GSL_SF_EXPINT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* E_1(x) := Re[ Integrate[ Exp[-xt]/t, {t,1,Infinity}] ] + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_E1_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_E1(const double x); + + +/* E_2(x) := Re[ Integrate[ Exp[-xt]/t^2, {t,1,Infinity}] ] + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_E2_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_E2(const double x); + + +/* E_n(x) := Re[ Integrate[ Exp[-xt]/t^n, {t,1,Infinity}] ] + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_En_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_expint_En(const int n, const double x); + + +/* E_1_scaled(x) := exp(x) E_1(x) + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_E1_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_E1_scaled(const double x); + + +/* E_2_scaled(x) := exp(x) E_2(x) + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_E2_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_E2_scaled(const double x); + +/* E_n_scaled(x) := exp(x) E_n(x) + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_En_scaled_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_expint_En_scaled(const int n, const double x); + + +/* Ei(x) := - PV Integrate[ Exp[-t]/t, {t,-x,Infinity}] + * := PV Integrate[ Exp[t]/t, {t,-Infinity,x}] + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_Ei_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_Ei(const double x); + + +/* Ei_scaled(x) := exp(-x) Ei(x) + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_expint_Ei_scaled_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_Ei_scaled(const double x); + + +/* Shi(x) := Integrate[ Sinh[t]/t, {t,0,x}] + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_Shi_e(const double x, gsl_sf_result * result); +double gsl_sf_Shi(const double x); + + +/* Chi(x) := Re[ M_EULER + log(x) + Integrate[(Cosh[t]-1)/t, {t,0,x}] ] + * + * x != 0.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_Chi_e(const double x, gsl_sf_result * result); +double gsl_sf_Chi(const double x); + + +/* Ei_3(x) := Integral[ Exp[-t^3], {t,0,x}] + * + * x >= 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_expint_3_e(const double x, gsl_sf_result * result); +double gsl_sf_expint_3(double x); + + +/* Si(x) := Integrate[ Sin[t]/t, {t,0,x}] + * + * exceptions: none + */ +int gsl_sf_Si_e(const double x, gsl_sf_result * result); +double gsl_sf_Si(const double x); + + +/* Ci(x) := -Integrate[ Cos[t]/t, {t,x,Infinity}] + * + * x > 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_Ci_e(const double x, gsl_sf_result * result); +double gsl_sf_Ci(const double x); + + +/* AtanInt(x) := Integral[ Arctan[t]/t, {t,0,x}] + * + * + * exceptions: + */ +int gsl_sf_atanint_e(const double x, gsl_sf_result * result); +double gsl_sf_atanint(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_EXPINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_fermi_dirac.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_fermi_dirac.h new file mode 100644 index 0000000..8f708cd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_fermi_dirac.h @@ -0,0 +1,126 @@ +/* specfunc/gsl_sf_fermi_dirac.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_FERMI_DIRAC_H__ +#define __GSL_SF_FERMI_DIRAC_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Complete Fermi-Dirac Integrals: + * + * F_j(x) := 1/Gamma[j+1] Integral[ t^j /(Exp[t-x] + 1), {t,0,Infinity}] + * + * + * Incomplete Fermi-Dirac Integrals: + * + * F_j(x,b) := 1/Gamma[j+1] Integral[ t^j /(Exp[t-x] + 1), {t,b,Infinity}] + */ + + +/* Complete integral F_{-1}(x) = e^x / (1 + e^x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_fermi_dirac_m1_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_m1(const double x); + + +/* Complete integral F_0(x) = ln(1 + e^x) + * + * exceptions: GSL_EUNDRFLW + */ +int gsl_sf_fermi_dirac_0_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_0(const double x); + + +/* Complete integral F_1(x) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_1_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_1(const double x); + + +/* Complete integral F_2(x) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_2_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_2(const double x); + + +/* Complete integral F_j(x) + * for integer j + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_int_e(const int j, const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_int(const int j, const double x); + + +/* Complete integral F_{-1/2}(x) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_mhalf_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_mhalf(const double x); + + +/* Complete integral F_{1/2}(x) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_half_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_half(const double x); + + +/* Complete integral F_{3/2}(x) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_fermi_dirac_3half_e(const double x, gsl_sf_result * result); +double gsl_sf_fermi_dirac_3half(const double x); + + +/* Incomplete integral F_0(x,b) = ln(1 + e^(b-x)) - (b-x) + * + * exceptions: GSL_EUNDRFLW, GSL_EDOM + */ +int gsl_sf_fermi_dirac_inc_0_e(const double x, const double b, gsl_sf_result * result); +double gsl_sf_fermi_dirac_inc_0(const double x, const double b); + + +__END_DECLS + +#endif /* __GSL_SF_FERMI_DIRAC_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gamma.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gamma.h new file mode 100644 index 0000000..d5e867b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gamma.h @@ -0,0 +1,293 @@ +/* specfunc/gsl_sf_gamma.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_GAMMA_H__ +#define __GSL_SF_GAMMA_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Log[Gamma(x)], x not a negative integer + * Uses real Lanczos method. + * Returns the real part of Log[Gamma[x]] when x < 0, + * i.e. Log[|Gamma[x]|]. + * + * exceptions: GSL_EDOM, GSL_EROUND + */ +int gsl_sf_lngamma_e(double x, gsl_sf_result * result); +double gsl_sf_lngamma(const double x); + + +/* Log[Gamma(x)], x not a negative integer + * Uses real Lanczos method. Determines + * the sign of Gamma[x] as well as Log[|Gamma[x]|] for x < 0. + * So Gamma[x] = sgn * Exp[result_lg]. + * + * exceptions: GSL_EDOM, GSL_EROUND + */ +int gsl_sf_lngamma_sgn_e(double x, gsl_sf_result * result_lg, double *sgn); + + +/* Gamma(x), x not a negative integer + * Uses real Lanczos method. + * + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EROUND + */ +int gsl_sf_gamma_e(const double x, gsl_sf_result * result); +double gsl_sf_gamma(const double x); + + +/* Regulated Gamma Function, x > 0 + * Gamma^*(x) = Gamma(x)/(Sqrt[2Pi] x^(x-1/2) exp(-x)) + * = (1 + 1/(12x) + ...), x->Inf + * A useful suggestion of Temme. + * + * exceptions: GSL_EDOM + */ +int gsl_sf_gammastar_e(const double x, gsl_sf_result * result); +double gsl_sf_gammastar(const double x); + + +/* 1/Gamma(x) + * Uses real Lanczos method. + * + * exceptions: GSL_EUNDRFLW, GSL_EROUND + */ +int gsl_sf_gammainv_e(const double x, gsl_sf_result * result); +double gsl_sf_gammainv(const double x); + + +/* Log[Gamma(z)] for z complex, z not a negative integer + * Uses complex Lanczos method. Note that the phase part (arg) + * is not well-determined when |z| is very large, due + * to inevitable roundoff in restricting to (-Pi,Pi]. + * This will raise the GSL_ELOSS exception when it occurs. + * The absolute value part (lnr), however, never suffers. + * + * Calculates: + * lnr = log|Gamma(z)| + * arg = arg(Gamma(z)) in (-Pi, Pi] + * + * exceptions: GSL_EDOM, GSL_ELOSS + */ +int gsl_sf_lngamma_complex_e(double zr, double zi, gsl_sf_result * lnr, gsl_sf_result * arg); + + +/* x^n / n! + * + * x >= 0.0, n >= 0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_taylorcoeff_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_taylorcoeff(const int n, const double x); + + +/* n! + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_fact_e(const unsigned int n, gsl_sf_result * result); +double gsl_sf_fact(const unsigned int n); + + +/* n!! = n(n-2)(n-4) ... + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_doublefact_e(const unsigned int n, gsl_sf_result * result); +double gsl_sf_doublefact(const unsigned int n); + + +/* log(n!) + * Faster than ln(Gamma(n+1)) for n < 170; defers for larger n. + * + * exceptions: none + */ +int gsl_sf_lnfact_e(const unsigned int n, gsl_sf_result * result); +double gsl_sf_lnfact(const unsigned int n); + + +/* log(n!!) + * + * exceptions: none + */ +int gsl_sf_lndoublefact_e(const unsigned int n, gsl_sf_result * result); +double gsl_sf_lndoublefact(const unsigned int n); + + +/* log(n choose m) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_lnchoose_e(unsigned int n, unsigned int m, gsl_sf_result * result); +double gsl_sf_lnchoose(unsigned int n, unsigned int m); + + +/* n choose m + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_choose_e(unsigned int n, unsigned int m, gsl_sf_result * result); +double gsl_sf_choose(unsigned int n, unsigned int m); + + +/* Logarithm of Pochhammer (Apell) symbol + * log( (a)_x ) + * where (a)_x := Gamma[a + x]/Gamma[a] + * + * a > 0, a+x > 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_lnpoch_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_lnpoch(const double a, const double x); + + +/* Logarithm of Pochhammer (Apell) symbol, with sign information. + * result = log( |(a)_x| ) + * sgn = sgn( (a)_x ) + * where (a)_x := Gamma[a + x]/Gamma[a] + * + * a != neg integer, a+x != neg integer + * + * exceptions: GSL_EDOM + */ +int gsl_sf_lnpoch_sgn_e(const double a, const double x, gsl_sf_result * result, double * sgn); + + +/* Pochhammer (Apell) symbol + * (a)_x := Gamma[a + x]/Gamma[x] + * + * a != neg integer, a+x != neg integer + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_poch_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_poch(const double a, const double x); + + +/* Relative Pochhammer (Apell) symbol + * ((a,x) - 1)/x + * where (a,x) = (a)_x := Gamma[a + x]/Gamma[a] + * + * exceptions: GSL_EDOM + */ +int gsl_sf_pochrel_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_pochrel(const double a, const double x); + + +/* Normalized Incomplete Gamma Function + * + * Q(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,x,Infinity} ] + * + * a >= 0, x >= 0 + * Q(a,0) := 1 + * Q(0,x) := 0, x != 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_gamma_inc_Q_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_gamma_inc_Q(const double a, const double x); + + +/* Complementary Normalized Incomplete Gamma Function + * + * P(a,x) = 1/Gamma(a) Integral[ t^(a-1) e^(-t), {t,0,x} ] + * + * a > 0, x >= 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_gamma_inc_P_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_gamma_inc_P(const double a, const double x); + + +/* Non-normalized Incomplete Gamma Function + * + * Gamma(a,x) := Integral[ t^(a-1) e^(-t), {t,x,Infinity} ] + * + * x >= 0.0 + * Gamma(a, 0) := Gamma(a) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_gamma_inc_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_gamma_inc(const double a, const double x); + + +/* Logarithm of Beta Function + * Log[B(a,b)] + * + * a > 0, b > 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_lnbeta_e(const double a, const double b, gsl_sf_result * result); +double gsl_sf_lnbeta(const double a, const double b); + +int gsl_sf_lnbeta_sgn_e(const double x, const double y, gsl_sf_result * result, double * sgn); + + +/* Beta Function + * B(a,b) + * + * a > 0, b > 0 + * exceptions: GSL_EDOM, GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_beta_e(const double a, const double b, gsl_sf_result * result); +double gsl_sf_beta(const double a, const double b); + + +/* Normalized Incomplete Beta Function + * B_x(a,b)/B(a,b) + * + * a > 0, b > 0, 0 <= x <= 1 + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_beta_inc_e(const double a, const double b, const double x, gsl_sf_result * result); +double gsl_sf_beta_inc(const double a, const double b, const double x); + + +/* The maximum x such that gamma(x) is not + * considered an overflow. + */ +#define GSL_SF_GAMMA_XMAX 171.0 + +/* The maximum n such that gsl_sf_fact(n) does not give an overflow. */ +#define GSL_SF_FACT_NMAX 170 + +/* The maximum n such that gsl_sf_doublefact(n) does not give an overflow. */ +#define GSL_SF_DOUBLEFACT_NMAX 297 + +__END_DECLS + +#endif /* __GSL_SF_GAMMA_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gegenbauer.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gegenbauer.h new file mode 100644 index 0000000..bf41d21 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_gegenbauer.h @@ -0,0 +1,73 @@ +/* specfunc/gsl_sf_gegenbauer.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_GEGENBAUER_H__ +#define __GSL_SF_GEGENBAUER_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Evaluate Gegenbauer polynomials + * using explicit representations. + * + * exceptions: none + */ +int gsl_sf_gegenpoly_1_e(double lambda, double x, gsl_sf_result * result); +int gsl_sf_gegenpoly_2_e(double lambda, double x, gsl_sf_result * result); +int gsl_sf_gegenpoly_3_e(double lambda, double x, gsl_sf_result * result); +double gsl_sf_gegenpoly_1(double lambda, double x); +double gsl_sf_gegenpoly_2(double lambda, double x); +double gsl_sf_gegenpoly_3(double lambda, double x); + + +/* Evaluate Gegenbauer polynomials. + * + * lambda > -1/2, n >= 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_gegenpoly_n_e(int n, double lambda, double x, gsl_sf_result * result); +double gsl_sf_gegenpoly_n(int n, double lambda, double x); + + +/* Calculate array of Gegenbauer polynomials + * for n = (0, 1, 2, ... nmax) + * + * lambda > -1/2, nmax >= 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_gegenpoly_array(int nmax, double lambda, double x, double * result_array); + + +__END_DECLS + +#endif /* __GSL_SF_GEGENBAUER_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hermite.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hermite.h new file mode 100644 index 0000000..39854d9 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hermite.h @@ -0,0 +1,98 @@ +/* gsl_sf_hermite.h + * + * Copyright (C) 2011-2014 Konrad Griessinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/*----------------------------------------------------------------------* + * (konradg(at)gmx.net) * + *----------------------------------------------------------------------*/ + +#ifndef __GSL_SF_HERMITE_H__ +#define __GSL_SF_HERMITE_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_sf_hermite_prob_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_prob(const int n, const double x); +int gsl_sf_hermite_prob_deriv_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_prob_deriv(const int m, const int n, const double x); +int gsl_sf_hermite_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite(const int n, const double x); +int gsl_sf_hermite_deriv_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_deriv(const int m, const int n, const double x); +int gsl_sf_hermite_func_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_func(const int n, const double x); +int gsl_sf_hermite_func_fast_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_func_fast(const int n, const double x); +int gsl_sf_hermite_prob_array(const int nmax, const double x, double * result_array); +int gsl_sf_hermite_prob_array_deriv(const int m, const int nmax, const double x, double * result_array); +int gsl_sf_hermite_prob_deriv_array(const int mmax, const int n, const double x, double * result_array); +int gsl_sf_hermite_prob_series_e(const int n, const double x, const double * a, gsl_sf_result * result); +double gsl_sf_hermite_prob_series(const int n, const double x, const double * a); +int gsl_sf_hermite_array(const int nmax, const double x, double * result_array); +int gsl_sf_hermite_array_deriv(const int m, const int nmax, const double x, double * result_array); +int gsl_sf_hermite_deriv_array(const int mmax, const int n, const double x, double * result_array); +int gsl_sf_hermite_series_e(const int n, const double x, const double * a, gsl_sf_result * result); +double gsl_sf_hermite_series(const int n, const double x, const double * a); +int gsl_sf_hermite_func_array(const int nmax, const double x, double * result_array); +int gsl_sf_hermite_func_series_e(const int n, const double x, const double * a, gsl_sf_result * result); +double gsl_sf_hermite_func_series(const int n, const double x, const double * a); +int gsl_sf_hermite_func_der_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_func_der(const int m, const int n, const double x); +int gsl_sf_hermite_prob_zero_e(const int n, const int s, gsl_sf_result * result); +double gsl_sf_hermite_prob_zero(const int n, const int s); +int gsl_sf_hermite_zero_e(const int n, const int s, gsl_sf_result * result); +double gsl_sf_hermite_zero(const int n, const int s); +int gsl_sf_hermite_func_zero_e(const int n, const int s, gsl_sf_result * result); +double gsl_sf_hermite_func_zero(const int n, const int s); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_sf_hermite_phys_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_phys(const int n, const double x); +int gsl_sf_hermite_phys_der_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_phys_der(const int m, const int n, const double x); +int gsl_sf_hermite_phys_array(const int nmax, const double x, double * result_array); +int gsl_sf_hermite_phys_series_e(const int n, const double x, const double * a, gsl_sf_result * result); +double gsl_sf_hermite_phys_series(const int n, const double x, const double * a); +int gsl_sf_hermite_phys_array_der(const int m, const int nmax, const double x, double * result_array); +int gsl_sf_hermite_phys_der_array(const int mmax, const int n, const double x, double * result_array); +int gsl_sf_hermite_phys_zero_e(const int n, const int s, gsl_sf_result * result); +double gsl_sf_hermite_phys_zero(const int n, const int s); + +int gsl_sf_hermite_prob_array_der(const int m, const int nmax, const double x, double * result_array); +int gsl_sf_hermite_prob_der_array(const int mmax, const int n, const double x, double * result_array); +int gsl_sf_hermite_prob_der_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hermite_prob_der(const int m, const int n, const double x); + +#endif /* !GSL_DISABLE_DEPRECATED */ + +__END_DECLS + +#endif /* __GSL_SF_HERMITE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hyperg.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hyperg.h new file mode 100644 index 0000000..8366b88 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_hyperg.h @@ -0,0 +1,154 @@ +/* specfunc/gsl_sf_hyperg.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_HYPERG_H__ +#define __GSL_SF_HYPERG_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Hypergeometric function related to Bessel functions + * 0F1[c,x] = + * Gamma[c] x^(1/2(1-c)) I_{c-1}(2 Sqrt[x]) + * Gamma[c] (-x)^(1/2(1-c)) J_{c-1}(2 Sqrt[-x]) + * + * exceptions: GSL_EOVRFLW, GSL_EUNDRFLW + */ +int gsl_sf_hyperg_0F1_e(double c, double x, gsl_sf_result * result); +double gsl_sf_hyperg_0F1(const double c, const double x); + + +/* Confluent hypergeometric function for integer parameters. + * 1F1[m,n,x] = M(m,n,x) + * + * exceptions: + */ +int gsl_sf_hyperg_1F1_int_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_1F1_int(const int m, const int n, double x); + + +/* Confluent hypergeometric function. + * 1F1[a,b,x] = M(a,b,x) + * + * exceptions: + */ +int gsl_sf_hyperg_1F1_e(const double a, const double b, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_1F1(double a, double b, double x); + + +/* Confluent hypergeometric function for integer parameters. + * U(m,n,x) + * + * exceptions: + */ +int gsl_sf_hyperg_U_int_e(const int m, const int n, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_U_int(const int m, const int n, const double x); + + +/* Confluent hypergeometric function for integer parameters. + * U(m,n,x) + * + * exceptions: + */ +int gsl_sf_hyperg_U_int_e10_e(const int m, const int n, const double x, gsl_sf_result_e10 * result); + + +/* Confluent hypergeometric function. + * U(a,b,x) + * + * exceptions: + */ +int gsl_sf_hyperg_U_e(const double a, const double b, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_U(const double a, const double b, const double x); + + +/* Confluent hypergeometric function. + * U(a,b,x) + * + * exceptions: + */ +int gsl_sf_hyperg_U_e10_e(const double a, const double b, const double x, gsl_sf_result_e10 * result); + + +/* Gauss hypergeometric function 2F1[a,b,c,x] + * |x| < 1 + * + * exceptions: + */ +int gsl_sf_hyperg_2F1_e(double a, double b, const double c, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_2F1(double a, double b, double c, double x); + + +/* Gauss hypergeometric function + * 2F1[aR + I aI, aR - I aI, c, x] + * |x| < 1 + * + * exceptions: + */ +int gsl_sf_hyperg_2F1_conj_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_2F1_conj(double aR, double aI, double c, double x); + + +/* Renormalized Gauss hypergeometric function + * 2F1[a,b,c,x] / Gamma[c] + * |x| < 1 + * + * exceptions: + */ +int gsl_sf_hyperg_2F1_renorm_e(const double a, const double b, const double c, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_2F1_renorm(double a, double b, double c, double x); + + +/* Renormalized Gauss hypergeometric function + * 2F1[aR + I aI, aR - I aI, c, x] / Gamma[c] + * |x| < 1 + * + * exceptions: + */ +int gsl_sf_hyperg_2F1_conj_renorm_e(const double aR, const double aI, const double c, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_2F1_conj_renorm(double aR, double aI, double c, double x); + + +/* Mysterious hypergeometric function. The series representation + * is a divergent hypergeometric series. However, for x < 0 we + * have 2F0(a,b,x) = (-1/x)^a U(a,1+a-b,-1/x) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_hyperg_2F0_e(const double a, const double b, const double x, gsl_sf_result * result); +double gsl_sf_hyperg_2F0(const double a, const double b, const double x); + + +__END_DECLS + +#endif /* __GSL_SF_HYPERG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_laguerre.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_laguerre.h new file mode 100644 index 0000000..0d7f1c3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_laguerre.h @@ -0,0 +1,68 @@ +/* specfunc/gsl_sf_laguerre.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_LAGUERRE_H__ +#define __GSL_SF_LAGUERRE_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* L^a_n(x) = (a+1)_n / n! 1F1(-n,a+1,x) */ + + +/* Evaluate generalized Laguerre polynomials + * using explicit representations. + * + * exceptions: none + */ +int gsl_sf_laguerre_1_e(const double a, const double x, gsl_sf_result * result); +int gsl_sf_laguerre_2_e(const double a, const double x, gsl_sf_result * result); +int gsl_sf_laguerre_3_e(const double a, const double x, gsl_sf_result * result); +double gsl_sf_laguerre_1(double a, double x); +double gsl_sf_laguerre_2(double a, double x); +double gsl_sf_laguerre_3(double a, double x); + + +/* Evaluate generalized Laguerre polynomials. + * + * a > -1.0 + * n >= 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_laguerre_n_e(const int n, const double a, const double x, gsl_sf_result * result); +double gsl_sf_laguerre_n(int n, double a, double x); + + +__END_DECLS + +#endif /* __GSL_SF_LAGUERRE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_lambert.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_lambert.h new file mode 100644 index 0000000..53b70a3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_lambert.h @@ -0,0 +1,69 @@ +/* specfunc/gsl_sf_lambert.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_LAMBERT_H__ +#define __GSL_SF_LAMBERT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Lambert's Function W_0(x) + * + * W_0(x) is the principal branch of the + * implicit function defined by W e^W = x. + * + * -1/E < x < \infty + * + * exceptions: GSL_EMAXITER; + */ +int gsl_sf_lambert_W0_e(double x, gsl_sf_result * result); +double gsl_sf_lambert_W0(double x); + + +/* Lambert's Function W_{-1}(x) + * + * W_{-1}(x) is the second real branch of the + * implicit function defined by W e^W = x. + * It agrees with W_0(x) when x >= 0. + * + * -1/E < x < \infty + * + * exceptions: GSL_MAXITER; + */ +int gsl_sf_lambert_Wm1_e(double x, gsl_sf_result * result); +double gsl_sf_lambert_Wm1(double x); + + +__END_DECLS + +#endif /* __GSL_SF_LAMBERT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_legendre.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_legendre.h new file mode 100644 index 0000000..f2b5244 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_legendre.h @@ -0,0 +1,395 @@ +/* specfunc/gsl_sf_legendre.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Gerard Jungman + * Copyright (C) 2019 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_LEGENDRE_H__ +#define __GSL_SF_LEGENDRE_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* P_l(x) l >= 0; |x| <= 1 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Pl_e(const int l, const double x, gsl_sf_result * result); +double gsl_sf_legendre_Pl(const int l, const double x); + + +/* P_l(x) for l=0,...,lmax; |x| <= 1 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Pl_array( + const int lmax, const double x, + double * result_array + ); + + +/* P_l(x) and P_l'(x) for l=0,...,lmax; |x| <= 1 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Pl_deriv_array( + const int lmax, const double x, + double * result_array, + double * result_deriv_array + ); + + +/* P_l(x), l=1,2,3 + * + * exceptions: none + */ +int gsl_sf_legendre_P1_e(double x, gsl_sf_result * result); +int gsl_sf_legendre_P2_e(double x, gsl_sf_result * result); +int gsl_sf_legendre_P3_e(double x, gsl_sf_result * result); +double gsl_sf_legendre_P1(const double x); +double gsl_sf_legendre_P2(const double x); +double gsl_sf_legendre_P3(const double x); + + +/* Q_0(x), x > -1, x != 1 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Q0_e(const double x, gsl_sf_result * result); +double gsl_sf_legendre_Q0(const double x); + + +/* Q_1(x), x > -1, x != 1 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Q1_e(const double x, gsl_sf_result * result); +double gsl_sf_legendre_Q1(const double x); + + +/* Q_l(x), x > -1, x != 1, l >= 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_Ql_e(const int l, const double x, gsl_sf_result * result); +double gsl_sf_legendre_Ql(const int l, const double x); + + +/* P_l^m(x) m >= 0; l >= m; |x| <= 1.0 + * + * Note that this function grows combinatorially with l. + * Therefore we can easily generate an overflow for l larger + * than about 150. + * + * There is no trouble for small m, but when m and l are both large, + * then there will be trouble. Rather than allow overflows, these + * functions refuse to calculate when they can sense that l and m are + * too big. + * + * If you really want to calculate a spherical harmonic, then DO NOT + * use this. Instead use legendre_sphPlm() below, which uses a similar + * recursion, but with the normalized functions. + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_legendre_Plm_e(const int l, const int m, const double x, gsl_sf_result * result); +double gsl_sf_legendre_Plm(const int l, const int m, const double x); + + +/* P_l^m(x) m >= 0; l >= m; |x| <= 1.0 + * l=|m|,...,lmax + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_legendre_Plm_array( + const int lmax, const int m, const double x, + double * result_array + ); + + +/* P_l^m(x) and d(P_l^m(x))/dx; m >= 0; lmax >= m; |x| <= 1.0 + * l=|m|,...,lmax + * + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_legendre_Plm_deriv_array( + const int lmax, const int m, const double x, + double * result_array, + double * result_deriv_array + ); + + +/* P_l^m(x), normalized properly for use in spherical harmonics + * m >= 0; l >= m; |x| <= 1.0 + * + * There is no overflow problem, as there is for the + * standard normalization of P_l^m(x). + * + * Specifically, it returns: + * + * sqrt((2l+1)/(4pi)) sqrt((l-m)!/(l+m)!) P_l^m(x) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_sphPlm_e(const int l, int m, const double x, gsl_sf_result * result); +double gsl_sf_legendre_sphPlm(const int l, const int m, const double x); + + +/* sphPlm(l,m,x) values + * m >= 0; l >= m; |x| <= 1.0 + * l=|m|,...,lmax + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_sphPlm_array( + const int lmax, int m, const double x, + double * result_array + ); + + +/* sphPlm(l,m,x) and d(sphPlm(l,m,x))/dx values + * m >= 0; l >= m; |x| <= 1.0 + * l=|m|,...,lmax + * + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_sphPlm_deriv_array( + const int lmax, const int m, const double x, + double * result_array, + double * result_deriv_array + ); + + + +/* size of result_array[] needed for the array versions of Plm + * (lmax - m + 1) + */ +int gsl_sf_legendre_array_size(const int lmax, const int m); + +/* Irregular Spherical Conical Function + * P^{1/2}_{-1/2 + I lambda}(x) + * + * x > -1.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_half_e(const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_half(const double lambda, const double x); + + +/* Regular Spherical Conical Function + * P^{-1/2}_{-1/2 + I lambda}(x) + * + * x > -1.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_mhalf_e(const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_mhalf(const double lambda, const double x); + + +/* Conical Function + * P^{0}_{-1/2 + I lambda}(x) + * + * x > -1.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_0_e(const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_0(const double lambda, const double x); + + +/* Conical Function + * P^{1}_{-1/2 + I lambda}(x) + * + * x > -1.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_1_e(const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_1(const double lambda, const double x); + + +/* Regular Spherical Conical Function + * P^{-1/2-l}_{-1/2 + I lambda}(x) + * + * x > -1.0, l >= -1 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_sph_reg_e(const int l, const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_sph_reg(const int l, const double lambda, const double x); + + +/* Regular Cylindrical Conical Function + * P^{-m}_{-1/2 + I lambda}(x) + * + * x > -1.0, m >= -1 + * exceptions: GSL_EDOM + */ +int gsl_sf_conicalP_cyl_reg_e(const int m, const double lambda, const double x, gsl_sf_result * result); +double gsl_sf_conicalP_cyl_reg(const int m, const double lambda, const double x); + + +/* The following spherical functions are specializations + * of Legendre functions which give the regular eigenfunctions + * of the Laplacian on a 3-dimensional hyperbolic space. + * Of particular interest is the flat limit, which is + * Flat-Lim := {lambda->Inf, eta->0, lambda*eta fixed}. + */ + +/* Zeroth radial eigenfunction of the Laplacian on the + * 3-dimensional hyperbolic space. + * + * legendre_H3d_0(lambda,eta) := sin(lambda*eta)/(lambda*sinh(eta)) + * + * Normalization: + * Flat-Lim legendre_H3d_0(lambda,eta) = j_0(lambda*eta) + * + * eta >= 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_H3d_0_e(const double lambda, const double eta, gsl_sf_result * result); +double gsl_sf_legendre_H3d_0(const double lambda, const double eta); + + +/* First radial eigenfunction of the Laplacian on the + * 3-dimensional hyperbolic space. + * + * legendre_H3d_1(lambda,eta) := + * 1/sqrt(lambda^2 + 1) sin(lam eta)/(lam sinh(eta)) + * (coth(eta) - lambda cot(lambda*eta)) + * + * Normalization: + * Flat-Lim legendre_H3d_1(lambda,eta) = j_1(lambda*eta) + * + * eta >= 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_H3d_1_e(const double lambda, const double eta, gsl_sf_result * result); +double gsl_sf_legendre_H3d_1(const double lambda, const double eta); + + +/* l'th radial eigenfunction of the Laplacian on the + * 3-dimensional hyperbolic space. + * + * Normalization: + * Flat-Lim legendre_H3d_l(l,lambda,eta) = j_l(lambda*eta) + * + * eta >= 0.0, l >= 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_legendre_H3d_e(const int l, const double lambda, const double eta, gsl_sf_result * result); +double gsl_sf_legendre_H3d(const int l, const double lambda, const double eta); + + +/* Array of H3d(ell), 0 <= ell <= lmax + */ +int gsl_sf_legendre_H3d_array(const int lmax, const double lambda, const double eta, double * result_array); + +/* associated legendre P_{lm} routines */ + +typedef enum +{ + GSL_SF_LEGENDRE_SCHMIDT, + GSL_SF_LEGENDRE_SPHARM, + GSL_SF_LEGENDRE_FULL, + GSL_SF_LEGENDRE_NONE +} gsl_sf_legendre_t; + +int gsl_sf_legendre_array(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + double result_array[]); +int gsl_sf_legendre_array_e(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + const double csphase, + double result_array[]); +int gsl_sf_legendre_deriv_array(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + double result_array[], + double result_deriv_array[]); +int gsl_sf_legendre_deriv_array_e(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + const double csphase, + double result_array[], + double result_deriv_array[]); +int gsl_sf_legendre_deriv_alt_array(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + double result_array[], + double result_deriv_array[]); +int gsl_sf_legendre_deriv_alt_array_e(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + const double csphase, + double result_array[], + double result_deriv_array[]); +int gsl_sf_legendre_deriv2_array(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + double result_array[], + double result_deriv_array[], + double result_deriv2_array[]); +int gsl_sf_legendre_deriv2_array_e(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + const double csphase, + double result_array[], + double result_deriv_array[], + double result_deriv2_array[]); +int gsl_sf_legendre_deriv2_alt_array(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + double result_array[], + double result_deriv_array[], + double result_deriv2_array[]); +int gsl_sf_legendre_deriv2_alt_array_e(const gsl_sf_legendre_t norm, + const size_t lmax, const double x, + const double csphase, + double result_array[], + double result_deriv_array[], + double result_deriv2_array[]); +size_t gsl_sf_legendre_array_n(const size_t lmax); +size_t gsl_sf_legendre_nlm(const size_t lmax); + +INLINE_DECL size_t gsl_sf_legendre_array_index(const size_t l, const size_t m); + +#ifdef HAVE_INLINE + +/* +gsl_sf_legendre_array_index() +This routine computes the index into a result_array[] corresponding +to a given (l,m) +*/ +INLINE_FUN +size_t +gsl_sf_legendre_array_index(const size_t l, const size_t m) +{ + return (((l * (l + 1)) >> 1) + m); +} + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_SF_LEGENDRE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_log.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_log.h new file mode 100644 index 0000000..92aa685 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_log.h @@ -0,0 +1,82 @@ +/* specfunc/gsl_sf_log.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_LOG_H__ +#define __GSL_SF_LOG_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Provide a logarithm function with GSL semantics. + * + * exceptions: GSL_EDOM + */ +int gsl_sf_log_e(const double x, gsl_sf_result * result); +double gsl_sf_log(const double x); + + +/* Log(|x|) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_log_abs_e(const double x, gsl_sf_result * result); +double gsl_sf_log_abs(const double x); + + +/* Complex Logarithm + * exp(lnr + I theta) = zr + I zi + * Returns argument in [-pi,pi]. + * + * exceptions: GSL_EDOM + */ +int gsl_sf_complex_log_e(const double zr, const double zi, gsl_sf_result * lnr, gsl_sf_result * theta); + + +/* Log(1 + x) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_log_1plusx_e(const double x, gsl_sf_result * result); +double gsl_sf_log_1plusx(const double x); + + +/* Log(1 + x) - x + * + * exceptions: GSL_EDOM + */ +int gsl_sf_log_1plusx_mx_e(const double x, gsl_sf_result * result); +double gsl_sf_log_1plusx_mx(const double x); + +__END_DECLS + +#endif /* __GSL_SF_LOG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_mathieu.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_mathieu.h new file mode 100644 index 0000000..8dc8d14 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_mathieu.h @@ -0,0 +1,113 @@ +/* specfunc/gsl_sf_mathieu.h + * + * Copyright (C) 2002 Lowell Johnson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* Author: L. Johnson */ + +#ifndef __GSL_SF_MATHIEU_H__ +#define __GSL_SF_MATHIEU_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +#define GSL_SF_MATHIEU_COEFF 100 + +typedef struct +{ + size_t size; + size_t even_order; + size_t odd_order; + int extra_values; + double qa; /* allow for caching of results: not implemented yet */ + double qb; /* allow for caching of results: not implemented yet */ + double *aa; + double *bb; + double *dd; + double *ee; + double *tt; + double *e2; + double *zz; + gsl_vector *eval; + gsl_matrix *evec; + gsl_eigen_symmv_workspace *wmat; +} gsl_sf_mathieu_workspace; + + +/* Compute an array of characteristic (eigen) values from the recurrence + matrices for the Mathieu equations. */ +int gsl_sf_mathieu_a_array(int order_min, int order_max, double qq, gsl_sf_mathieu_workspace *work, double result_array[]); +int gsl_sf_mathieu_b_array(int order_min, int order_max, double qq, gsl_sf_mathieu_workspace *work, double result_array[]); + +/* Compute the characteristic value for a Mathieu function of order n and + type ntype. */ +int gsl_sf_mathieu_a_e(int order, double qq, gsl_sf_result *result); +double gsl_sf_mathieu_a(int order, double qq); +int gsl_sf_mathieu_b_e(int order, double qq, gsl_sf_result *result); +double gsl_sf_mathieu_b(int order, double qq); + +/* Compute the Fourier coefficients for a Mathieu function. */ +int gsl_sf_mathieu_a_coeff(int order, double qq, double aa, double coeff[]); +int gsl_sf_mathieu_b_coeff(int order, double qq, double aa, double coeff[]); + +/* Allocate computational storage space for eigenvalue solution. */ +gsl_sf_mathieu_workspace *gsl_sf_mathieu_alloc(const size_t nn, + const double qq); +void gsl_sf_mathieu_free(gsl_sf_mathieu_workspace *workspace); + +/* Compute an angular Mathieu function. */ +int gsl_sf_mathieu_ce_e(int order, double qq, double zz, gsl_sf_result *result); +double gsl_sf_mathieu_ce(int order, double qq, double zz); +int gsl_sf_mathieu_se_e(int order, double qq, double zz, gsl_sf_result *result); +double gsl_sf_mathieu_se(int order, double qq, double zz); +int gsl_sf_mathieu_ce_array(int nmin, int nmax, double qq, double zz, + gsl_sf_mathieu_workspace *work, + double result_array[]); +int gsl_sf_mathieu_se_array(int nmin, int nmax, double qq, double zz, + gsl_sf_mathieu_workspace *work, + double result_array[]); + +/* Compute a radial Mathieu function. */ +int gsl_sf_mathieu_Mc_e(int kind, int order, double qq, double zz, + gsl_sf_result *result); +double gsl_sf_mathieu_Mc(int kind, int order, double qq, double zz); +int gsl_sf_mathieu_Ms_e(int kind, int order, double qq, double zz, + gsl_sf_result *result); +double gsl_sf_mathieu_Ms(int kind, int order, double qq, double zz); +int gsl_sf_mathieu_Mc_array(int kind, int nmin, int nmax, double qq, + double zz, gsl_sf_mathieu_workspace *work, + double result_array[]); +int gsl_sf_mathieu_Ms_array(int kind, int nmin, int nmax, double qq, + double zz, gsl_sf_mathieu_workspace *work, + double result_array[]); + + +__END_DECLS + +#endif /* !__GSL_SF_MATHIEU_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_pow_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_pow_int.h new file mode 100644 index 0000000..e535d57 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_pow_int.h @@ -0,0 +1,49 @@ +/* specfunc/gsl_sf_pow_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_POW_INT_H__ +#define __GSL_SF_POW_INT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Calculate x^n. + * Does not check for overflow/underflow. + */ +int gsl_sf_pow_int_e(double x, int n, gsl_sf_result * result); +double gsl_sf_pow_int(const double x, const int n); + + +__END_DECLS + +#endif /* __GSL_SF_POW_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_psi.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_psi.h new file mode 100644 index 0000000..ec61179 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_psi.h @@ -0,0 +1,113 @@ +/* specfunc/gsl_sf_psi.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_PSI_H__ +#define __GSL_SF_PSI_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Poly-Gamma Functions + * + * psi(m,x) := (d/dx)^m psi(0,x) = (d/dx)^{m+1} log(gamma(x)) + */ + + +/* Di-Gamma Function psi(n) = psi(0,n) + * + * n > 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_psi_int_e(const int n, gsl_sf_result * result); +double gsl_sf_psi_int(const int n); + + +/* Di-Gamma Function psi(x) = psi(0, x) + * + * x != 0.0, -1.0, -2.0, ... + * exceptions: GSL_EDOM, GSL_ELOSS + */ +int gsl_sf_psi_e(const double x, gsl_sf_result * result); +double gsl_sf_psi(const double x); + + +/* Di-Gamma Function Re[psi(1 + I y)] + * + * exceptions: none + */ +int gsl_sf_psi_1piy_e(const double y, gsl_sf_result * result); +double gsl_sf_psi_1piy(const double y); + + +/* Di-Gamma Function psi(z) for general complex argument z = x + iy + * + * exceptions: GSL_EDOM + */ +int gsl_sf_complex_psi_e( + const double x, + const double y, + gsl_sf_result * result_re, + gsl_sf_result * result_im + ); + + +/* Tri-Gamma Function psi^(1)(n) + * + * n > 0 + * exceptions: GSL_EDOM + */ +int gsl_sf_psi_1_int_e(const int n, gsl_sf_result * result); +double gsl_sf_psi_1_int(const int n); + + +/* Tri-Gamma Function psi^(1)(x) + * + * x != 0.0, -1.0, -2.0, ... + * exceptions: GSL_EDOM, GSL_ELOSS + */ +int gsl_sf_psi_1_e(const double x, gsl_sf_result * result); +double gsl_sf_psi_1(const double x); + + +/* Poly-Gamma Function psi^(n)(x) + * + * n >= 0, x > 0.0 + * exceptions: GSL_EDOM + */ +int gsl_sf_psi_n_e(const int n, const double x, gsl_sf_result * result); +double gsl_sf_psi_n(const int n, const double x); + + +__END_DECLS + +#endif /* __GSL_SF_PSI_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_result.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_result.h new file mode 100644 index 0000000..512bad7 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_result.h @@ -0,0 +1,59 @@ +/* specfunc/gsl_sf_result.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_RESULT_H__ +#define __GSL_SF_RESULT_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +struct gsl_sf_result_struct { + double val; + double err; +}; +typedef struct gsl_sf_result_struct gsl_sf_result; + +#define GSL_SF_RESULT_SET(r,v,e) do { (r)->val=(v); (r)->err=(e); } while(0) + + +struct gsl_sf_result_e10_struct { + double val; + double err; + int e10; +}; +typedef struct gsl_sf_result_e10_struct gsl_sf_result_e10; + + +int gsl_sf_result_smash_e(const gsl_sf_result_e10 * re, gsl_sf_result * r); + + +__END_DECLS + +#endif /* __GSL_SF_RESULT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_sincos_pi.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_sincos_pi.h new file mode 100644 index 0000000..62fafbe --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_sincos_pi.h @@ -0,0 +1,57 @@ +/* specfunc/gsl_sf_sincos_pi.h + * + * Copyright (C) 2017 Konrad Griessinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman, K. Griessinger */ + +#ifndef __GSL_SF_SINCOS_PI_H__ +#define __GSL_SF_SINCOS_PI_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* sin_pi(x) with GSL semantics. This is actually important + * because we want to control the error estimate, and trying + * to guess the error for the standard library implementation + * every time it is used would be a little goofy. + */ +int gsl_sf_sin_pi_e(double x, gsl_sf_result * result); +double gsl_sf_sin_pi(const double x); + + +/* cos_pi(x) with GSL semantics. + */ +int gsl_sf_cos_pi_e(double x, gsl_sf_result * result); +double gsl_sf_cos_pi(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_SINCOS_PI_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_synchrotron.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_synchrotron.h new file mode 100644 index 0000000..26028c8 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_synchrotron.h @@ -0,0 +1,60 @@ +/* specfunc/gsl_sf_synchrotron.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_SYNCHROTRON_H__ +#define __GSL_SF_SYNCHROTRON_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* First synchrotron function: + * synchrotron_1(x) = x Integral[ K_{5/3}(t), {t, x, Infinity}] + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_synchrotron_1_e(const double x, gsl_sf_result * result); +double gsl_sf_synchrotron_1(const double x); + + +/* Second synchroton function: + * synchrotron_2(x) = x * K_{2/3}(x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_synchrotron_2_e(const double x, gsl_sf_result * result); +double gsl_sf_synchrotron_2(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_SYNCHROTRON_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_transport.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_transport.h new file mode 100644 index 0000000..c0fd7fc --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_transport.h @@ -0,0 +1,78 @@ +/* specfunc/gsl_sf_transport.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_TRANSPORT_H__ +#define __GSL_SF_TRANSPORT_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Transport function: + * J(n,x) := Integral[ t^n e^t /(e^t - 1)^2, {t,0,x}] + */ + +/* J(2,x) + * + * exceptions: GSL_EDOM + */ +int gsl_sf_transport_2_e(const double x, gsl_sf_result * result); +double gsl_sf_transport_2(const double x); + + +/* J(3,x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_transport_3_e(const double x, gsl_sf_result * result); +double gsl_sf_transport_3(const double x); + + +/* J(4,x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_transport_4_e(const double x, gsl_sf_result * result); +double gsl_sf_transport_4(const double x); + + +/* J(5,x) + * + * exceptions: GSL_EDOM, GSL_EUNDRFLW + */ +int gsl_sf_transport_5_e(const double x, gsl_sf_result * result); +double gsl_sf_transport_5(const double x); + + +__END_DECLS + +#endif /* __GSL_SF_TRANSPORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_trig.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_trig.h new file mode 100644 index 0000000..e2c5722 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_trig.h @@ -0,0 +1,152 @@ +/* specfunc/gsl_sf_trig.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_TRIG_H__ +#define __GSL_SF_TRIG_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Sin(x) with GSL semantics. This is actually important + * because we want to control the error estimate, and trying + * to guess the error for the standard library implementation + * every time it is used would be a little goofy. + */ +int gsl_sf_sin_e(double x, gsl_sf_result * result); +double gsl_sf_sin(const double x); + + +/* Cos(x) with GSL semantics. + */ +int gsl_sf_cos_e(double x, gsl_sf_result * result); +double gsl_sf_cos(const double x); + + +/* Hypot(x,y) with GSL semantics. + */ +int gsl_sf_hypot_e(const double x, const double y, gsl_sf_result * result); +double gsl_sf_hypot(const double x, const double y); + + +/* Sin(z) for complex z + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_complex_sin_e(const double zr, const double zi, gsl_sf_result * szr, gsl_sf_result * szi); + + +/* Cos(z) for complex z + * + * exceptions: GSL_EOVRFLW + */ +int gsl_sf_complex_cos_e(const double zr, const double zi, gsl_sf_result * czr, gsl_sf_result * czi); + + +/* Log(Sin(z)) for complex z + * + * exceptions: GSL_EDOM, GSL_ELOSS + */ +int gsl_sf_complex_logsin_e(const double zr, const double zi, gsl_sf_result * lszr, gsl_sf_result * lszi); + + +/* Sinc(x) = sin(pi x) / (pi x) + * + * exceptions: none + */ +int gsl_sf_sinc_e(double x, gsl_sf_result * result); +double gsl_sf_sinc(const double x); + + +/* Log(Sinh(x)), x > 0 + * + * exceptions: GSL_EDOM + */ +int gsl_sf_lnsinh_e(const double x, gsl_sf_result * result); +double gsl_sf_lnsinh(const double x); + + +/* Log(Cosh(x)) + * + * exceptions: none + */ +int gsl_sf_lncosh_e(const double x, gsl_sf_result * result); +double gsl_sf_lncosh(const double x); + + +/* Convert polar to rectlinear coordinates. + * + * exceptions: GSL_ELOSS + */ +int gsl_sf_polar_to_rect(const double r, const double theta, gsl_sf_result * x, gsl_sf_result * y); + +/* Convert rectilinear to polar coordinates. + * return argument in range [-pi, pi] + * + * exceptions: GSL_EDOM + */ +int gsl_sf_rect_to_polar(const double x, const double y, gsl_sf_result * r, gsl_sf_result * theta); + +/* Sin(x) for quantity with an associated error. + */ +int gsl_sf_sin_err_e(const double x, const double dx, gsl_sf_result * result); + + +/* Cos(x) for quantity with an associated error. + */ +int gsl_sf_cos_err_e(const double x, const double dx, gsl_sf_result * result); + + +/* Force an angle to lie in the range (-pi,pi]. + * + * exceptions: GSL_ELOSS + */ +int gsl_sf_angle_restrict_symm_e(double * theta); +double gsl_sf_angle_restrict_symm(const double theta); + + +/* Force an angle to lie in the range [0, 2pi) + * + * exceptions: GSL_ELOSS + */ +int gsl_sf_angle_restrict_pos_e(double * theta); +double gsl_sf_angle_restrict_pos(const double theta); + + +int gsl_sf_angle_restrict_symm_err_e(const double theta, gsl_sf_result * result); + +int gsl_sf_angle_restrict_pos_err_e(const double theta, gsl_sf_result * result); + + +__END_DECLS + +#endif /* __GSL_SF_TRIG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sf_zeta.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_zeta.h new file mode 100644 index 0000000..2d7fad0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sf_zeta.h @@ -0,0 +1,112 @@ +/* specfunc/gsl_sf_zeta.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2004 Gerard Jungman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + +#ifndef __GSL_SF_ZETA_H__ +#define __GSL_SF_ZETA_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* Riemann Zeta Function + * zeta(n) = Sum[ k^(-n), {k,1,Infinity} ] + * + * n=integer, n != 1 + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_zeta_int_e(const int n, gsl_sf_result * result); +double gsl_sf_zeta_int(const int n); + + +/* Riemann Zeta Function + * zeta(x) = Sum[ k^(-s), {k,1,Infinity} ], s != 1.0 + * + * s != 1.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_zeta_e(const double s, gsl_sf_result * result); +double gsl_sf_zeta(const double s); + + +/* Riemann Zeta Function minus 1 + * useful for evaluating the fractional part + * of Riemann zeta for large argument + * + * s != 1.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_zetam1_e(const double s, gsl_sf_result * result); +double gsl_sf_zetam1(const double s); + + +/* Riemann Zeta Function minus 1 for integer arg + * useful for evaluating the fractional part + * of Riemann zeta for large argument + * + * s != 1.0 + * exceptions: GSL_EDOM, GSL_EOVRFLW + */ +int gsl_sf_zetam1_int_e(const int s, gsl_sf_result * result); +double gsl_sf_zetam1_int(const int s); + + +/* Hurwitz Zeta Function + * zeta(s,q) = Sum[ (k+q)^(-s), {k,0,Infinity} ] + * + * s > 1.0, q > 0.0 + * exceptions: GSL_EDOM, GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_hzeta_e(const double s, const double q, gsl_sf_result * result); +double gsl_sf_hzeta(const double s, const double q); + + +/* Eta Function + * eta(n) = (1-2^(1-n)) zeta(n) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_eta_int_e(int n, gsl_sf_result * result); +double gsl_sf_eta_int(const int n); + + +/* Eta Function + * eta(s) = (1-2^(1-s)) zeta(s) + * + * exceptions: GSL_EUNDRFLW, GSL_EOVRFLW + */ +int gsl_sf_eta_e(const double s, gsl_sf_result * result); +double gsl_sf_eta(const double s); + + +__END_DECLS + +#endif /* __GSL_SF_ZETA_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_siman.h b/ChaosDataPlayer/GSL/include/gsl/gsl_siman.h new file mode 100644 index 0000000..a16f7c7 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_siman.h @@ -0,0 +1,82 @@ +/* siman/gsl_siman.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Mark Galassi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SIMAN_H__ +#define __GSL_SIMAN_H__ +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* types for the function pointers passed to gsl_siman_solve */ + +typedef double (*gsl_siman_Efunc_t) (void *xp); +typedef void (*gsl_siman_step_t) (const gsl_rng *r, void *xp, double step_size); +typedef double (*gsl_siman_metric_t) (void *xp, void *yp); +typedef void (*gsl_siman_print_t) (void *xp); +typedef void (*gsl_siman_copy_t) (void *source, void *dest); +typedef void * (*gsl_siman_copy_construct_t) (void *xp); +typedef void (*gsl_siman_destroy_t) (void *xp); + +/* this structure contains all the information needed to structure the + search, beyond the energy function, the step function and the + initial guess. */ + +typedef struct { + int n_tries; /* how many points to try for each step */ + int iters_fixed_T; /* how many iterations at each temperature? */ + double step_size; /* max step size in the random walk */ + /* the following parameters are for the Boltzmann distribution */ + double k, t_initial, mu_t, t_min; +} gsl_siman_params_t; + +/* prototype for the workhorse function */ + +void gsl_siman_solve(const gsl_rng * r, + void *x0_p, gsl_siman_Efunc_t Ef, + gsl_siman_step_t take_step, + gsl_siman_metric_t distance, + gsl_siman_print_t print_position, + gsl_siman_copy_t copyfunc, + gsl_siman_copy_construct_t copy_constructor, + gsl_siman_destroy_t destructor, + size_t element_size, + gsl_siman_params_t params); + +void +gsl_siman_solve_many (const gsl_rng * r, void *x0_p, gsl_siman_Efunc_t Ef, + gsl_siman_step_t take_step, + gsl_siman_metric_t distance, + gsl_siman_print_t print_position, + size_t element_size, + gsl_siman_params_t params); + +__END_DECLS + +#endif /* __GSL_SIMAN_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort.h new file mode 100644 index 0000000..b1496c2 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort.h @@ -0,0 +1,20 @@ +#ifndef __GSL_SORT_H__ +#define __GSL_SORT_H__ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_SORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_char.h new file mode 100644 index 0000000..a4bf351 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_char.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_CHAR_H__ +#define __GSL_SORT_CHAR_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_char (char * data, const size_t stride, const size_t n); +void gsl_sort2_char (char * data1, const size_t stride1, char * data2, const size_t stride2, const size_t n); +void gsl_sort_char_index (size_t * p, const char * data, const size_t stride, const size_t n); + +int gsl_sort_char_smallest (char * dest, const size_t k, const char * src, const size_t stride, const size_t n); +int gsl_sort_char_smallest_index (size_t * p, const size_t k, const char * src, const size_t stride, const size_t n); + +int gsl_sort_char_largest (char * dest, const size_t k, const char * src, const size_t stride, const size_t n); +int gsl_sort_char_largest_index (size_t * p, const size_t k, const char * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_double.h new file mode 100644 index 0000000..3f67f43 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_double.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_DOUBLE_H__ +#define __GSL_SORT_DOUBLE_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort (double * data, const size_t stride, const size_t n); +void gsl_sort2 (double * data1, const size_t stride1, double * data2, const size_t stride2, const size_t n); +void gsl_sort_index (size_t * p, const double * data, const size_t stride, const size_t n); + +int gsl_sort_smallest (double * dest, const size_t k, const double * src, const size_t stride, const size_t n); +int gsl_sort_smallest_index (size_t * p, const size_t k, const double * src, const size_t stride, const size_t n); + +int gsl_sort_largest (double * dest, const size_t k, const double * src, const size_t stride, const size_t n); +int gsl_sort_largest_index (size_t * p, const size_t k, const double * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_float.h new file mode 100644 index 0000000..505a1c6 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_float.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_FLOAT_H__ +#define __GSL_SORT_FLOAT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_float (float * data, const size_t stride, const size_t n); +void gsl_sort2_float (float * data1, const size_t stride1, float * data2, const size_t stride2, const size_t n); +void gsl_sort_float_index (size_t * p, const float * data, const size_t stride, const size_t n); + +int gsl_sort_float_smallest (float * dest, const size_t k, const float * src, const size_t stride, const size_t n); +int gsl_sort_float_smallest_index (size_t * p, const size_t k, const float * src, const size_t stride, const size_t n); + +int gsl_sort_float_largest (float * dest, const size_t k, const float * src, const size_t stride, const size_t n); +int gsl_sort_float_largest_index (size_t * p, const size_t k, const float * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_int.h new file mode 100644 index 0000000..7aa8d38 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_int.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_INT_H__ +#define __GSL_SORT_INT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_int (int * data, const size_t stride, const size_t n); +void gsl_sort2_int (int * data1, const size_t stride1, int * data2, const size_t stride2, const size_t n); +void gsl_sort_int_index (size_t * p, const int * data, const size_t stride, const size_t n); + +int gsl_sort_int_smallest (int * dest, const size_t k, const int * src, const size_t stride, const size_t n); +int gsl_sort_int_smallest_index (size_t * p, const size_t k, const int * src, const size_t stride, const size_t n); + +int gsl_sort_int_largest (int * dest, const size_t k, const int * src, const size_t stride, const size_t n); +int gsl_sort_int_largest_index (size_t * p, const size_t k, const int * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long.h new file mode 100644 index 0000000..7f4d689 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_LONG_H__ +#define __GSL_SORT_LONG_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_long (long * data, const size_t stride, const size_t n); +void gsl_sort2_long (long * data1, const size_t stride1, long * data2, const size_t stride2, const size_t n); +void gsl_sort_long_index (size_t * p, const long * data, const size_t stride, const size_t n); + +int gsl_sort_long_smallest (long * dest, const size_t k, const long * src, const size_t stride, const size_t n); +int gsl_sort_long_smallest_index (size_t * p, const size_t k, const long * src, const size_t stride, const size_t n); + +int gsl_sort_long_largest (long * dest, const size_t k, const long * src, const size_t stride, const size_t n); +int gsl_sort_long_largest_index (size_t * p, const size_t k, const long * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long_double.h new file mode 100644 index 0000000..164fd23 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_long_double.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_LONG_DOUBLE_H__ +#define __GSL_SORT_LONG_DOUBLE_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_long_double (long double * data, const size_t stride, const size_t n); +void gsl_sort2_long_double (long double * data1, const size_t stride1, long double * data2, const size_t stride2, const size_t n); +void gsl_sort_long_double_index (size_t * p, const long double * data, const size_t stride, const size_t n); + +int gsl_sort_long_double_smallest (long double * dest, const size_t k, const long double * src, const size_t stride, const size_t n); +int gsl_sort_long_double_smallest_index (size_t * p, const size_t k, const long double * src, const size_t stride, const size_t n); + +int gsl_sort_long_double_largest (long double * dest, const size_t k, const long double * src, const size_t stride, const size_t n); +int gsl_sort_long_double_largest_index (size_t * p, const size_t k, const long double * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_short.h new file mode 100644 index 0000000..4626e9e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_short.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_SHORT_H__ +#define __GSL_SORT_SHORT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_short (short * data, const size_t stride, const size_t n); +void gsl_sort2_short (short * data1, const size_t stride1, short * data2, const size_t stride2, const size_t n); +void gsl_sort_short_index (size_t * p, const short * data, const size_t stride, const size_t n); + +int gsl_sort_short_smallest (short * dest, const size_t k, const short * src, const size_t stride, const size_t n); +int gsl_sort_short_smallest_index (size_t * p, const size_t k, const short * src, const size_t stride, const size_t n); + +int gsl_sort_short_largest (short * dest, const size_t k, const short * src, const size_t stride, const size_t n); +int gsl_sort_short_largest_index (size_t * p, const size_t k, const short * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uchar.h new file mode 100644 index 0000000..6cd511d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uchar.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_UCHAR_H__ +#define __GSL_SORT_UCHAR_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_uchar (unsigned char * data, const size_t stride, const size_t n); +void gsl_sort2_uchar (unsigned char * data1, const size_t stride1, unsigned char * data2, const size_t stride2, const size_t n); +void gsl_sort_uchar_index (size_t * p, const unsigned char * data, const size_t stride, const size_t n); + +int gsl_sort_uchar_smallest (unsigned char * dest, const size_t k, const unsigned char * src, const size_t stride, const size_t n); +int gsl_sort_uchar_smallest_index (size_t * p, const size_t k, const unsigned char * src, const size_t stride, const size_t n); + +int gsl_sort_uchar_largest (unsigned char * dest, const size_t k, const unsigned char * src, const size_t stride, const size_t n); +int gsl_sort_uchar_largest_index (size_t * p, const size_t k, const unsigned char * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uint.h new file mode 100644 index 0000000..639e596 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_uint.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_UINT_H__ +#define __GSL_SORT_UINT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_uint (unsigned int * data, const size_t stride, const size_t n); +void gsl_sort2_uint (unsigned int * data1, const size_t stride1, unsigned int * data2, const size_t stride2, const size_t n); +void gsl_sort_uint_index (size_t * p, const unsigned int * data, const size_t stride, const size_t n); + +int gsl_sort_uint_smallest (unsigned int * dest, const size_t k, const unsigned int * src, const size_t stride, const size_t n); +int gsl_sort_uint_smallest_index (size_t * p, const size_t k, const unsigned int * src, const size_t stride, const size_t n); + +int gsl_sort_uint_largest (unsigned int * dest, const size_t k, const unsigned int * src, const size_t stride, const size_t n); +int gsl_sort_uint_largest_index (size_t * p, const size_t k, const unsigned int * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ulong.h new file mode 100644 index 0000000..4f8e41d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ulong.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_ULONG_H__ +#define __GSL_SORT_ULONG_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_ulong (unsigned long * data, const size_t stride, const size_t n); +void gsl_sort2_ulong (unsigned long * data1, const size_t stride1, unsigned long * data2, const size_t stride2, const size_t n); +void gsl_sort_ulong_index (size_t * p, const unsigned long * data, const size_t stride, const size_t n); + +int gsl_sort_ulong_smallest (unsigned long * dest, const size_t k, const unsigned long * src, const size_t stride, const size_t n); +int gsl_sort_ulong_smallest_index (size_t * p, const size_t k, const unsigned long * src, const size_t stride, const size_t n); + +int gsl_sort_ulong_largest (unsigned long * dest, const size_t k, const unsigned long * src, const size_t stride, const size_t n); +int gsl_sort_ulong_largest_index (size_t * p, const size_t k, const unsigned long * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ushort.h new file mode 100644 index 0000000..6da3d10 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_ushort.h @@ -0,0 +1,51 @@ +/* sort/gsl_sort_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_USHORT_H__ +#define __GSL_SORT_USHORT_H__ + +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_ushort (unsigned short * data, const size_t stride, const size_t n); +void gsl_sort2_ushort (unsigned short * data1, const size_t stride1, unsigned short * data2, const size_t stride2, const size_t n); +void gsl_sort_ushort_index (size_t * p, const unsigned short * data, const size_t stride, const size_t n); + +int gsl_sort_ushort_smallest (unsigned short * dest, const size_t k, const unsigned short * src, const size_t stride, const size_t n); +int gsl_sort_ushort_smallest_index (size_t * p, const size_t k, const unsigned short * src, const size_t stride, const size_t n); + +int gsl_sort_ushort_largest (unsigned short * dest, const size_t k, const unsigned short * src, const size_t stride, const size_t n); +int gsl_sort_ushort_largest_index (size_t * p, const size_t k, const unsigned short * src, const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_SORT_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector.h new file mode 100644 index 0000000..d65a9ee --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector.h @@ -0,0 +1,20 @@ +#ifndef __GSL_SORT_VECTOR_H__ +#define __GSL_SORT_VECTOR_H__ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_SORT_VECTOR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_char.h new file mode 100644 index 0000000..39721fb --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_char.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_CHAR_H__ +#define __GSL_SORT_VECTOR_CHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_char (gsl_vector_char * v); +void gsl_sort_vector2_char (gsl_vector_char * v1, gsl_vector_char * v2); +int gsl_sort_vector_char_index (gsl_permutation * p, const gsl_vector_char * v); + +int gsl_sort_vector_char_smallest (char * dest, const size_t k, const gsl_vector_char * v); +int gsl_sort_vector_char_largest (char * dest, const size_t k, const gsl_vector_char * v); + +int gsl_sort_vector_char_smallest_index (size_t * p, const size_t k, const gsl_vector_char * v); +int gsl_sort_vector_char_largest_index (size_t * p, const size_t k, const gsl_vector_char * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_double.h new file mode 100644 index 0000000..f60a744 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_double.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_DOUBLE_H__ +#define __GSL_SORT_VECTOR_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector (gsl_vector * v); +void gsl_sort_vector2 (gsl_vector * v1, gsl_vector * v2); +int gsl_sort_vector_index (gsl_permutation * p, const gsl_vector * v); + +int gsl_sort_vector_smallest (double * dest, const size_t k, const gsl_vector * v); +int gsl_sort_vector_largest (double * dest, const size_t k, const gsl_vector * v); + +int gsl_sort_vector_smallest_index (size_t * p, const size_t k, const gsl_vector * v); +int gsl_sort_vector_largest_index (size_t * p, const size_t k, const gsl_vector * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_float.h new file mode 100644 index 0000000..fe035c3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_float.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_FLOAT_H__ +#define __GSL_SORT_VECTOR_FLOAT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_float (gsl_vector_float * v); +void gsl_sort_vector2_float (gsl_vector_float * v1, gsl_vector_float * v2); +int gsl_sort_vector_float_index (gsl_permutation * p, const gsl_vector_float * v); + +int gsl_sort_vector_float_smallest (float * dest, const size_t k, const gsl_vector_float * v); +int gsl_sort_vector_float_largest (float * dest, const size_t k, const gsl_vector_float * v); + +int gsl_sort_vector_float_smallest_index (size_t * p, const size_t k, const gsl_vector_float * v); +int gsl_sort_vector_float_largest_index (size_t * p, const size_t k, const gsl_vector_float * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_int.h new file mode 100644 index 0000000..3179bca --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_int.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_INT_H__ +#define __GSL_SORT_VECTOR_INT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_int (gsl_vector_int * v); +void gsl_sort_vector2_int (gsl_vector_int * v1, gsl_vector_int * v2); +int gsl_sort_vector_int_index (gsl_permutation * p, const gsl_vector_int * v); + +int gsl_sort_vector_int_smallest (int * dest, const size_t k, const gsl_vector_int * v); +int gsl_sort_vector_int_largest (int * dest, const size_t k, const gsl_vector_int * v); + +int gsl_sort_vector_int_smallest_index (size_t * p, const size_t k, const gsl_vector_int * v); +int gsl_sort_vector_int_largest_index (size_t * p, const size_t k, const gsl_vector_int * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long.h new file mode 100644 index 0000000..41eebec --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_LONG_H__ +#define __GSL_SORT_VECTOR_LONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_long (gsl_vector_long * v); +void gsl_sort_vector2_long (gsl_vector_long * v1, gsl_vector_long * v2); +int gsl_sort_vector_long_index (gsl_permutation * p, const gsl_vector_long * v); + +int gsl_sort_vector_long_smallest (long * dest, const size_t k, const gsl_vector_long * v); +int gsl_sort_vector_long_largest (long * dest, const size_t k, const gsl_vector_long * v); + +int gsl_sort_vector_long_smallest_index (size_t * p, const size_t k, const gsl_vector_long * v); +int gsl_sort_vector_long_largest_index (size_t * p, const size_t k, const gsl_vector_long * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long_double.h new file mode 100644 index 0000000..4409d06 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_long_double.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_LONG_DOUBLE_H__ +#define __GSL_SORT_VECTOR_LONG_DOUBLE_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_long_double (gsl_vector_long_double * v); +void gsl_sort_vector2_long_double (gsl_vector_long_double * v1, gsl_vector_long_double * v2); +int gsl_sort_vector_long_double_index (gsl_permutation * p, const gsl_vector_long_double * v); + +int gsl_sort_vector_long_double_smallest (long double * dest, const size_t k, const gsl_vector_long_double * v); +int gsl_sort_vector_long_double_largest (long double * dest, const size_t k, const gsl_vector_long_double * v); + +int gsl_sort_vector_long_double_smallest_index (size_t * p, const size_t k, const gsl_vector_long_double * v); +int gsl_sort_vector_long_double_largest_index (size_t * p, const size_t k, const gsl_vector_long_double * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_short.h new file mode 100644 index 0000000..f25e869 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_short.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_SHORT_H__ +#define __GSL_SORT_VECTOR_SHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_short (gsl_vector_short * v); +void gsl_sort_vector2_short (gsl_vector_short * v1, gsl_vector_short * v2); +int gsl_sort_vector_short_index (gsl_permutation * p, const gsl_vector_short * v); + +int gsl_sort_vector_short_smallest (short * dest, const size_t k, const gsl_vector_short * v); +int gsl_sort_vector_short_largest (short * dest, const size_t k, const gsl_vector_short * v); + +int gsl_sort_vector_short_smallest_index (size_t * p, const size_t k, const gsl_vector_short * v); +int gsl_sort_vector_short_largest_index (size_t * p, const size_t k, const gsl_vector_short * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uchar.h new file mode 100644 index 0000000..edc3408 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uchar.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_UCHAR_H__ +#define __GSL_SORT_VECTOR_UCHAR_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_uchar (gsl_vector_uchar * v); +void gsl_sort_vector2_uchar (gsl_vector_uchar * v1, gsl_vector_uchar * v2); +int gsl_sort_vector_uchar_index (gsl_permutation * p, const gsl_vector_uchar * v); + +int gsl_sort_vector_uchar_smallest (unsigned char * dest, const size_t k, const gsl_vector_uchar * v); +int gsl_sort_vector_uchar_largest (unsigned char * dest, const size_t k, const gsl_vector_uchar * v); + +int gsl_sort_vector_uchar_smallest_index (size_t * p, const size_t k, const gsl_vector_uchar * v); +int gsl_sort_vector_uchar_largest_index (size_t * p, const size_t k, const gsl_vector_uchar * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uint.h new file mode 100644 index 0000000..6e45b84 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_uint.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_UINT_H__ +#define __GSL_SORT_VECTOR_UINT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_uint (gsl_vector_uint * v); +void gsl_sort_vector2_uint (gsl_vector_uint * v1, gsl_vector_uint * v2); +int gsl_sort_vector_uint_index (gsl_permutation * p, const gsl_vector_uint * v); + +int gsl_sort_vector_uint_smallest (unsigned int * dest, const size_t k, const gsl_vector_uint * v); +int gsl_sort_vector_uint_largest (unsigned int * dest, const size_t k, const gsl_vector_uint * v); + +int gsl_sort_vector_uint_smallest_index (size_t * p, const size_t k, const gsl_vector_uint * v); +int gsl_sort_vector_uint_largest_index (size_t * p, const size_t k, const gsl_vector_uint * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ulong.h new file mode 100644 index 0000000..e651057 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ulong.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_ULONG_H__ +#define __GSL_SORT_VECTOR_ULONG_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_ulong (gsl_vector_ulong * v); +void gsl_sort_vector2_ulong (gsl_vector_ulong * v1, gsl_vector_ulong * v2); +int gsl_sort_vector_ulong_index (gsl_permutation * p, const gsl_vector_ulong * v); + +int gsl_sort_vector_ulong_smallest (unsigned long * dest, const size_t k, const gsl_vector_ulong * v); +int gsl_sort_vector_ulong_largest (unsigned long * dest, const size_t k, const gsl_vector_ulong * v); + +int gsl_sort_vector_ulong_smallest_index (size_t * p, const size_t k, const gsl_vector_ulong * v); +int gsl_sort_vector_ulong_largest_index (size_t * p, const size_t k, const gsl_vector_ulong * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ushort.h new file mode 100644 index 0000000..09eb0bd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sort_vector_ushort.h @@ -0,0 +1,52 @@ +/* sort/gsl_sort_vector_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Thomas Walter, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SORT_VECTOR_USHORT_H__ +#define __GSL_SORT_VECTOR_USHORT_H__ + +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void gsl_sort_vector_ushort (gsl_vector_ushort * v); +void gsl_sort_vector2_ushort (gsl_vector_ushort * v1, gsl_vector_ushort * v2); +int gsl_sort_vector_ushort_index (gsl_permutation * p, const gsl_vector_ushort * v); + +int gsl_sort_vector_ushort_smallest (unsigned short * dest, const size_t k, const gsl_vector_ushort * v); +int gsl_sort_vector_ushort_largest (unsigned short * dest, const size_t k, const gsl_vector_ushort * v); + +int gsl_sort_vector_ushort_smallest_index (size_t * p, const size_t k, const gsl_vector_ushort * v); +int gsl_sort_vector_ushort_largest_index (size_t * p, const size_t k, const gsl_vector_ushort * v); + +__END_DECLS + +#endif /* __GSL_SORT_VECTOR_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spblas.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spblas.h new file mode 100644 index 0000000..9bf9da3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spblas.h @@ -0,0 +1,58 @@ +/* gsl_spblas.h + * + * Copyright (C) 2012-2014 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPBLAS_H__ +#define __GSL_SPBLAS_H__ + +#include + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * Prototypes + */ + +int gsl_spblas_dgemv(const CBLAS_TRANSPOSE_t TransA, const double alpha, + const gsl_spmatrix *A, const gsl_vector *x, + const double beta, gsl_vector *y); +int gsl_spblas_dgemm(const double alpha, const gsl_spmatrix *A, + const gsl_spmatrix *B, gsl_spmatrix *C); +size_t gsl_spblas_scatter(const gsl_spmatrix *A, const size_t j, + const double alpha, int *w, double *x, + const int mark, gsl_spmatrix *C, size_t nz); + +__END_DECLS + +#endif /* __GSL_SPBLAS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_specfunc.h b/ChaosDataPlayer/GSL/include/gsl/gsl_specfunc.h new file mode 100644 index 0000000..e07b5aa --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_specfunc.h @@ -0,0 +1,10 @@ +/* Author: G. Jungman */ + + +/* Convenience header */ +#ifndef __GSL_SPECFUNC_H__ +#define __GSL_SPECFUNC_H__ + +#include + +#endif /* __GSL_SPECFUNC_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_splinalg.h b/ChaosDataPlayer/GSL/include/gsl/gsl_splinalg.h new file mode 100644 index 0000000..265b6ae --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_splinalg.h @@ -0,0 +1,79 @@ +/* gsl_splinalg.h + * + * Copyright (C) 2012-2014 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPLINALG_H__ +#define __GSL_SPLINALG_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* iteration solver type */ +typedef struct +{ + const char *name; + void * (*alloc) (const size_t n, const size_t m); + int (*iterate) (const gsl_spmatrix *A, const gsl_vector *b, + const double tol, gsl_vector *x, void *); + double (*normr)(const void *); + void (*free) (void *); +} gsl_splinalg_itersolve_type; + +typedef struct +{ + const gsl_splinalg_itersolve_type * type; + double normr; /* current residual norm || b - A x || */ + void * state; +} gsl_splinalg_itersolve; + +/* available types */ +GSL_VAR const gsl_splinalg_itersolve_type * gsl_splinalg_itersolve_gmres; + +/* + * Prototypes + */ +gsl_splinalg_itersolve * +gsl_splinalg_itersolve_alloc(const gsl_splinalg_itersolve_type *T, + const size_t n, const size_t m); +void gsl_splinalg_itersolve_free(gsl_splinalg_itersolve *w); +const char *gsl_splinalg_itersolve_name(const gsl_splinalg_itersolve *w); +int gsl_splinalg_itersolve_iterate(const gsl_spmatrix *A, + const gsl_vector *b, + const double tol, gsl_vector *x, + gsl_splinalg_itersolve *w); +double gsl_splinalg_itersolve_normr(const gsl_splinalg_itersolve *w); + +__END_DECLS + +#endif /* __GSL_SPLINALG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spline.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spline.h new file mode 100644 index 0000000..08255ca --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spline.h @@ -0,0 +1,101 @@ +/* interpolation/gsl_spline.h + * + * Copyright (C) 2001, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPLINE_H__ +#define __GSL_SPLINE_H__ +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* general interpolation object */ +typedef struct { + gsl_interp * interp; + double * x; + double * y; + size_t size; +} gsl_spline; + +gsl_spline * +gsl_spline_alloc(const gsl_interp_type * T, size_t size); + +int +gsl_spline_init(gsl_spline * spline, const double xa[], const double ya[], size_t size); + +const char * gsl_spline_name(const gsl_spline * spline); +unsigned int gsl_spline_min_size(const gsl_spline * spline); + + +int +gsl_spline_eval_e(const gsl_spline * spline, double x, + gsl_interp_accel * a, double * y); + +double +gsl_spline_eval(const gsl_spline * spline, double x, gsl_interp_accel * a); + +int +gsl_spline_eval_deriv_e(const gsl_spline * spline, + double x, + gsl_interp_accel * a, + double * y); + +double +gsl_spline_eval_deriv(const gsl_spline * spline, + double x, + gsl_interp_accel * a); + +int +gsl_spline_eval_deriv2_e(const gsl_spline * spline, + double x, + gsl_interp_accel * a, + double * y); + +double +gsl_spline_eval_deriv2(const gsl_spline * spline, + double x, + gsl_interp_accel * a); + +int +gsl_spline_eval_integ_e(const gsl_spline * spline, + double a, double b, + gsl_interp_accel * acc, + double * y); + +double +gsl_spline_eval_integ(const gsl_spline * spline, + double a, double b, + gsl_interp_accel * acc); + +void +gsl_spline_free(gsl_spline * spline); + +__END_DECLS + +#endif /* __GSL_INTERP_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spline2d.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spline2d.h new file mode 100644 index 0000000..5f7e237 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spline2d.h @@ -0,0 +1,120 @@ +/* interpolation/gsl_spline2d.h + * + * Copyright 2012 David Zaslavsky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPLINE2D_H__ +#define __GSL_SPLINE2D_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + + +/* + * A 2D interpolation object which stores the arrays defining the function. + * In all other respects, this is just like a gsl_interp2d object. + */ +typedef struct +{ + gsl_interp2d interp_object; /* low-level interpolation object */ + double * xarr; /* x data array */ + double * yarr; /* y data array */ + double * zarr; /* z data array */ +} gsl_spline2d; + +gsl_spline2d * gsl_spline2d_alloc(const gsl_interp2d_type * T, size_t xsize, size_t ysize); + +int gsl_spline2d_init(gsl_spline2d * interp, const double xa[], + const double ya[], const double za[], + size_t xsize, size_t ysize); + +void gsl_spline2d_free(gsl_spline2d * interp); + +double gsl_spline2d_eval(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, + double * z); + +double gsl_spline2d_eval_extrap(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_extrap_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya, + double * z); + +double gsl_spline2d_eval_deriv_x(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_deriv_x_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +double gsl_spline2d_eval_deriv_y(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya); + +int gsl_spline2d_eval_deriv_y_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +double gsl_spline2d_eval_deriv_xx(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_deriv_xx_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +double gsl_spline2d_eval_deriv_yy(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_deriv_yy_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +double gsl_spline2d_eval_deriv_xy(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, gsl_interp_accel* ya); + +int gsl_spline2d_eval_deriv_xy_e(const gsl_spline2d * interp, const double x, + const double y, gsl_interp_accel* xa, + gsl_interp_accel* ya, double * z); + +size_t gsl_spline2d_min_size(const gsl_spline2d * interp); + +const char * gsl_spline2d_name(const gsl_spline2d * interp); + +int gsl_spline2d_set(const gsl_spline2d * interp, double zarr[], + const size_t i, const size_t j, const double z); +double gsl_spline2d_get(const gsl_spline2d * interp, const double zarr[], + const size_t i, const size_t j); + +__END_DECLS + +#endif /* __GSL_SPLINE2D_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix.h new file mode 100644 index 0000000..125d9a7 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix.h @@ -0,0 +1,62 @@ +#ifndef __GSL_SPMATRIX_H__ +#define __GSL_SPMATRIX_H__ + +enum +{ + GSL_SPMATRIX_COO = 0, /* coordinate/triplet representation */ + GSL_SPMATRIX_CSC = 1, /* compressed sparse column */ + GSL_SPMATRIX_CSR = 2, /* compressed sparse row */ + GSL_SPMATRIX_TRIPLET = GSL_SPMATRIX_COO, + GSL_SPMATRIX_CCS = GSL_SPMATRIX_CSC, + GSL_SPMATRIX_CRS = GSL_SPMATRIX_CSR +}; + +/* memory pool for binary tree node allocation */ +struct gsl_spmatrix_pool_node +{ + struct gsl_spmatrix_pool_node * next; + void * block_ptr; /* pointer to memory block, of size n*tree_node_size */ + unsigned char * free_slot; /* pointer to next available slot */ +}; + +typedef struct gsl_spmatrix_pool_node gsl_spmatrix_pool; + +#define GSL_SPMATRIX_ISCOO(m) ((m)->sptype == GSL_SPMATRIX_COO) +#define GSL_SPMATRIX_ISCSC(m) ((m)->sptype == GSL_SPMATRIX_CSC) +#define GSL_SPMATRIX_ISCSR(m) ((m)->sptype == GSL_SPMATRIX_CSR) + +#define GSL_SPMATRIX_ISTRIPLET(m) GSL_SPMATRIX_ISCOO(m) +#define GSL_SPMATRIX_ISCCS(m) GSL_SPMATRIX_ISCSC(m) +#define GSL_SPMATRIX_ISCRS(m) GSL_SPMATRIX_ISCSR(m) + +#define GSL_SPMATRIX_FLG_GROW (1 << 0) /* allow size of matrix to grow as elements are added */ +#define GSL_SPMATRIX_FLG_FIXED (1 << 1) /* sparsity pattern is fixed */ + +/* compare matrix entries (ia,ja) and (ib,jb) - sort by rows first, then by columns */ +#define GSL_SPMATRIX_COMPARE_ROWCOL(m,ia,ja,ib,jb) ((ia) < (ib) ? -1 : ((ia) > (ib) ? 1 : ((ja) < (jb) ? -1 : ((ja) > (jb))))) + +/* common/utility functions */ + +void gsl_spmatrix_cumsum(const size_t n, int * c); + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_SPMATRIX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_char.h new file mode 100644 index 0000000..bcb6464 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_char.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_char.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_CHAR_H__ +#define __GSL_SPMATRIX_CHAR_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + char *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(char),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + char *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_char; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_char * gsl_spmatrix_char_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_char * gsl_spmatrix_char_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_char_free (gsl_spmatrix_char * m); +int gsl_spmatrix_char_realloc (const size_t nzmax, gsl_spmatrix_char * m); +size_t gsl_spmatrix_char_nnz (const gsl_spmatrix_char * m); +const char * gsl_spmatrix_char_type (const gsl_spmatrix_char * m); +int gsl_spmatrix_char_set_zero (gsl_spmatrix_char * m); +int gsl_spmatrix_char_tree_rebuild (gsl_spmatrix_char * m); + +/* compress */ + +int gsl_spmatrix_char_csc (gsl_spmatrix_char * dest, const gsl_spmatrix_char * src); +int gsl_spmatrix_char_csr (gsl_spmatrix_char * dest, const gsl_spmatrix_char * src); +gsl_spmatrix_char * gsl_spmatrix_char_compress (const gsl_spmatrix_char * src, const int sptype); +gsl_spmatrix_char * gsl_spmatrix_char_compcol (const gsl_spmatrix_char * src); +gsl_spmatrix_char * gsl_spmatrix_char_ccs (const gsl_spmatrix_char * src); +gsl_spmatrix_char * gsl_spmatrix_char_crs (const gsl_spmatrix_char * src); + +/* copy */ + +int gsl_spmatrix_char_memcpy (gsl_spmatrix_char * dest, const gsl_spmatrix_char * src); + +/* file I/O */ + +int gsl_spmatrix_char_fprintf (FILE * stream, const gsl_spmatrix_char * m, const char * format); +gsl_spmatrix_char * gsl_spmatrix_char_fscanf (FILE * stream); +int gsl_spmatrix_char_fwrite (FILE * stream, const gsl_spmatrix_char * m); +int gsl_spmatrix_char_fread (FILE * stream, gsl_spmatrix_char * m); + +/* get/set */ + +char gsl_spmatrix_char_get (const gsl_spmatrix_char * m, const size_t i, const size_t j); +int gsl_spmatrix_char_set (gsl_spmatrix_char * m, const size_t i, const size_t j, const char x); +char * gsl_spmatrix_char_ptr (const gsl_spmatrix_char * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_char_minmax (const gsl_spmatrix_char * m, char * min_out, char * max_out); +int gsl_spmatrix_char_min_index (const gsl_spmatrix_char * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_char_scale (gsl_spmatrix_char * m, const char x); +int gsl_spmatrix_char_scale_columns (gsl_spmatrix_char * m, const gsl_vector_char * x); +int gsl_spmatrix_char_scale_rows (gsl_spmatrix_char * m, const gsl_vector_char * x); +int gsl_spmatrix_char_add (gsl_spmatrix_char * c, const gsl_spmatrix_char * a, const gsl_spmatrix_char * b); +int gsl_spmatrix_char_dense_add (gsl_matrix_char * a, const gsl_spmatrix_char * b); +int gsl_spmatrix_char_dense_sub (gsl_matrix_char * a, const gsl_spmatrix_char * b); +int gsl_spmatrix_char_d2sp (gsl_spmatrix_char * T, const gsl_matrix_char * A); +int gsl_spmatrix_char_sp2d (gsl_matrix_char * A, const gsl_spmatrix_char * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_char_add_to_dense (gsl_matrix_char * a, const gsl_spmatrix_char * b); + +#endif + +/* properties */ + +int gsl_spmatrix_char_equal (const gsl_spmatrix_char * a, const gsl_spmatrix_char * b); +char gsl_spmatrix_char_norm1 (const gsl_spmatrix_char * a); + +/* swap */ + +int gsl_spmatrix_char_transpose (gsl_spmatrix_char * m); +int gsl_spmatrix_char_transpose2 (gsl_spmatrix_char * m); +int gsl_spmatrix_char_transpose_memcpy (gsl_spmatrix_char * dest, const gsl_spmatrix_char * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_double.h new file mode 100644 index 0000000..6581f70 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_double.h @@ -0,0 +1,179 @@ +/* spmatrix/gsl_spmatrix_double.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_COMPLEX_DOUBLE_H__ +#define __GSL_SPMATRIX_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + double *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size 2*MAX(size1,size2)*MAX(sizeof(double),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + double *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_complex; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_complex * gsl_spmatrix_complex_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_complex * gsl_spmatrix_complex_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_complex_free (gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_realloc (const size_t nzmax, gsl_spmatrix_complex * m); +size_t gsl_spmatrix_complex_nnz (const gsl_spmatrix_complex * m); +const char * gsl_spmatrix_complex_type (const gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_set_zero (gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_tree_rebuild (gsl_spmatrix_complex * m); + +/* compress */ + +int gsl_spmatrix_complex_csc (gsl_spmatrix_complex * dest, const gsl_spmatrix_complex * src); +int gsl_spmatrix_complex_csr (gsl_spmatrix_complex * dest, const gsl_spmatrix_complex * src); +gsl_spmatrix_complex * gsl_spmatrix_complex_compress (const gsl_spmatrix_complex * src, const int sptype); +gsl_spmatrix_complex * gsl_spmatrix_complex_compcol (const gsl_spmatrix_complex * src); +gsl_spmatrix_complex * gsl_spmatrix_complex_ccs (const gsl_spmatrix_complex * src); +gsl_spmatrix_complex * gsl_spmatrix_complex_crs (const gsl_spmatrix_complex * src); + +/* copy */ + +int gsl_spmatrix_complex_memcpy (gsl_spmatrix_complex * dest, const gsl_spmatrix_complex * src); + +/* file I/O */ + +int gsl_spmatrix_complex_fprintf (FILE * stream, const gsl_spmatrix_complex * m, const char * format); +gsl_spmatrix_complex * gsl_spmatrix_complex_fscanf (FILE * stream); +int gsl_spmatrix_complex_fwrite (FILE * stream, const gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_fread (FILE * stream, gsl_spmatrix_complex * m); + +/* get/set */ + +gsl_complex gsl_spmatrix_complex_get (const gsl_spmatrix_complex * m, const size_t i, const size_t j); +int gsl_spmatrix_complex_set (gsl_spmatrix_complex * m, const size_t i, const size_t j, const gsl_complex x); +gsl_complex * gsl_spmatrix_complex_ptr (const gsl_spmatrix_complex * m, const size_t i, const size_t j); + +/* operations */ + +int gsl_spmatrix_complex_scale (gsl_spmatrix_complex * m, const gsl_complex x); +int gsl_spmatrix_complex_scale_columns (gsl_spmatrix_complex * m, const gsl_vector_complex * x); +int gsl_spmatrix_complex_scale_rows (gsl_spmatrix_complex * m, const gsl_vector_complex * x); +int gsl_spmatrix_complex_add (gsl_spmatrix_complex * c, const gsl_spmatrix_complex * a, const gsl_spmatrix_complex * b); +int gsl_spmatrix_complex_dense_add (gsl_matrix_complex * a, const gsl_spmatrix_complex * b); +int gsl_spmatrix_complex_dense_sub (gsl_matrix_complex * a, const gsl_spmatrix_complex * b); +int gsl_spmatrix_complex_d2sp (gsl_spmatrix_complex * T, const gsl_matrix_complex * A); +int gsl_spmatrix_complex_sp2d (gsl_matrix_complex * A, const gsl_spmatrix_complex * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_complex_add_to_dense (gsl_matrix_complex * a, const gsl_spmatrix_complex * b); + +#endif + +/* properties */ + +int gsl_spmatrix_complex_equal (const gsl_spmatrix_complex * a, const gsl_spmatrix_complex * b); + +/* swap */ + +int gsl_spmatrix_complex_transpose (gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_transpose2 (gsl_spmatrix_complex * m); +int gsl_spmatrix_complex_transpose_memcpy (gsl_spmatrix_complex * dest, const gsl_spmatrix_complex * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_float.h new file mode 100644 index 0000000..5b9ee50 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_float.h @@ -0,0 +1,179 @@ +/* spmatrix/gsl_spmatrix_float.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_COMPLEX_FLOAT_H__ +#define __GSL_SPMATRIX_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + float *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size 2*MAX(size1,size2)*MAX(sizeof(float),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + float *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_complex_float; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_complex_float_free (gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_realloc (const size_t nzmax, gsl_spmatrix_complex_float * m); +size_t gsl_spmatrix_complex_float_nnz (const gsl_spmatrix_complex_float * m); +const char * gsl_spmatrix_complex_float_type (const gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_set_zero (gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_tree_rebuild (gsl_spmatrix_complex_float * m); + +/* compress */ + +int gsl_spmatrix_complex_float_csc (gsl_spmatrix_complex_float * dest, const gsl_spmatrix_complex_float * src); +int gsl_spmatrix_complex_float_csr (gsl_spmatrix_complex_float * dest, const gsl_spmatrix_complex_float * src); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_compress (const gsl_spmatrix_complex_float * src, const int sptype); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_compcol (const gsl_spmatrix_complex_float * src); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_ccs (const gsl_spmatrix_complex_float * src); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_crs (const gsl_spmatrix_complex_float * src); + +/* copy */ + +int gsl_spmatrix_complex_float_memcpy (gsl_spmatrix_complex_float * dest, const gsl_spmatrix_complex_float * src); + +/* file I/O */ + +int gsl_spmatrix_complex_float_fprintf (FILE * stream, const gsl_spmatrix_complex_float * m, const char * format); +gsl_spmatrix_complex_float * gsl_spmatrix_complex_float_fscanf (FILE * stream); +int gsl_spmatrix_complex_float_fwrite (FILE * stream, const gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_fread (FILE * stream, gsl_spmatrix_complex_float * m); + +/* get/set */ + +gsl_complex_float gsl_spmatrix_complex_float_get (const gsl_spmatrix_complex_float * m, const size_t i, const size_t j); +int gsl_spmatrix_complex_float_set (gsl_spmatrix_complex_float * m, const size_t i, const size_t j, const gsl_complex_float x); +gsl_complex_float * gsl_spmatrix_complex_float_ptr (const gsl_spmatrix_complex_float * m, const size_t i, const size_t j); + +/* operations */ + +int gsl_spmatrix_complex_float_scale (gsl_spmatrix_complex_float * m, const gsl_complex_float x); +int gsl_spmatrix_complex_float_scale_columns (gsl_spmatrix_complex_float * m, const gsl_vector_complex_float * x); +int gsl_spmatrix_complex_float_scale_rows (gsl_spmatrix_complex_float * m, const gsl_vector_complex_float * x); +int gsl_spmatrix_complex_float_add (gsl_spmatrix_complex_float * c, const gsl_spmatrix_complex_float * a, const gsl_spmatrix_complex_float * b); +int gsl_spmatrix_complex_float_dense_add (gsl_matrix_complex_float * a, const gsl_spmatrix_complex_float * b); +int gsl_spmatrix_complex_float_dense_sub (gsl_matrix_complex_float * a, const gsl_spmatrix_complex_float * b); +int gsl_spmatrix_complex_float_d2sp (gsl_spmatrix_complex_float * T, const gsl_matrix_complex_float * A); +int gsl_spmatrix_complex_float_sp2d (gsl_matrix_complex_float * A, const gsl_spmatrix_complex_float * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_complex_float_add_to_dense (gsl_matrix_complex_float * a, const gsl_spmatrix_complex_float * b); + +#endif + +/* properties */ + +int gsl_spmatrix_complex_float_equal (const gsl_spmatrix_complex_float * a, const gsl_spmatrix_complex_float * b); + +/* swap */ + +int gsl_spmatrix_complex_float_transpose (gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_transpose2 (gsl_spmatrix_complex_float * m); +int gsl_spmatrix_complex_float_transpose_memcpy (gsl_spmatrix_complex_float * dest, const gsl_spmatrix_complex_float * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_long_double.h new file mode 100644 index 0000000..acf15f4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_complex_long_double.h @@ -0,0 +1,179 @@ +/* spmatrix/gsl_spmatrix_long_double.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_SPMATRIX_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + long double *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size 2*MAX(size1,size2)*MAX(sizeof(long double),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + long double *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_complex_long_double; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_complex_long_double_free (gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_realloc (const size_t nzmax, gsl_spmatrix_complex_long_double * m); +size_t gsl_spmatrix_complex_long_double_nnz (const gsl_spmatrix_complex_long_double * m); +const char * gsl_spmatrix_complex_long_double_type (const gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_set_zero (gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_tree_rebuild (gsl_spmatrix_complex_long_double * m); + +/* compress */ + +int gsl_spmatrix_complex_long_double_csc (gsl_spmatrix_complex_long_double * dest, const gsl_spmatrix_complex_long_double * src); +int gsl_spmatrix_complex_long_double_csr (gsl_spmatrix_complex_long_double * dest, const gsl_spmatrix_complex_long_double * src); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_compress (const gsl_spmatrix_complex_long_double * src, const int sptype); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_compcol (const gsl_spmatrix_complex_long_double * src); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_ccs (const gsl_spmatrix_complex_long_double * src); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_crs (const gsl_spmatrix_complex_long_double * src); + +/* copy */ + +int gsl_spmatrix_complex_long_double_memcpy (gsl_spmatrix_complex_long_double * dest, const gsl_spmatrix_complex_long_double * src); + +/* file I/O */ + +int gsl_spmatrix_complex_long_double_fprintf (FILE * stream, const gsl_spmatrix_complex_long_double * m, const char * format); +gsl_spmatrix_complex_long_double * gsl_spmatrix_complex_long_double_fscanf (FILE * stream); +int gsl_spmatrix_complex_long_double_fwrite (FILE * stream, const gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_fread (FILE * stream, gsl_spmatrix_complex_long_double * m); + +/* get/set */ + +gsl_complex_long_double gsl_spmatrix_complex_long_double_get (const gsl_spmatrix_complex_long_double * m, const size_t i, const size_t j); +int gsl_spmatrix_complex_long_double_set (gsl_spmatrix_complex_long_double * m, const size_t i, const size_t j, const gsl_complex_long_double x); +gsl_complex_long_double * gsl_spmatrix_complex_long_double_ptr (const gsl_spmatrix_complex_long_double * m, const size_t i, const size_t j); + +/* operations */ + +int gsl_spmatrix_complex_long_double_scale (gsl_spmatrix_complex_long_double * m, const gsl_complex_long_double x); +int gsl_spmatrix_complex_long_double_scale_columns (gsl_spmatrix_complex_long_double * m, const gsl_vector_complex_long_double * x); +int gsl_spmatrix_complex_long_double_scale_rows (gsl_spmatrix_complex_long_double * m, const gsl_vector_complex_long_double * x); +int gsl_spmatrix_complex_long_double_add (gsl_spmatrix_complex_long_double * c, const gsl_spmatrix_complex_long_double * a, const gsl_spmatrix_complex_long_double * b); +int gsl_spmatrix_complex_long_double_dense_add (gsl_matrix_complex_long_double * a, const gsl_spmatrix_complex_long_double * b); +int gsl_spmatrix_complex_long_double_dense_sub (gsl_matrix_complex_long_double * a, const gsl_spmatrix_complex_long_double * b); +int gsl_spmatrix_complex_long_double_d2sp (gsl_spmatrix_complex_long_double * T, const gsl_matrix_complex_long_double * A); +int gsl_spmatrix_complex_long_double_sp2d (gsl_matrix_complex_long_double * A, const gsl_spmatrix_complex_long_double * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_complex_long_double_add_to_dense (gsl_matrix_complex_long_double * a, const gsl_spmatrix_complex_long_double * b); + +#endif + +/* properties */ + +int gsl_spmatrix_complex_long_double_equal (const gsl_spmatrix_complex_long_double * a, const gsl_spmatrix_complex_long_double * b); + +/* swap */ + +int gsl_spmatrix_complex_long_double_transpose (gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_transpose2 (gsl_spmatrix_complex_long_double * m); +int gsl_spmatrix_complex_long_double_transpose_memcpy (gsl_spmatrix_complex_long_double * dest, const gsl_spmatrix_complex_long_double * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_double.h new file mode 100644 index 0000000..978f7a3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_double.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_double.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_DOUBLE_H__ +#define __GSL_SPMATRIX_DOUBLE_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + double *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(double),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + double *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix * gsl_spmatrix_alloc (const size_t n1, const size_t n2); +gsl_spmatrix * gsl_spmatrix_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_free (gsl_spmatrix * m); +int gsl_spmatrix_realloc (const size_t nzmax, gsl_spmatrix * m); +size_t gsl_spmatrix_nnz (const gsl_spmatrix * m); +const char * gsl_spmatrix_type (const gsl_spmatrix * m); +int gsl_spmatrix_set_zero (gsl_spmatrix * m); +int gsl_spmatrix_tree_rebuild (gsl_spmatrix * m); + +/* compress */ + +int gsl_spmatrix_csc (gsl_spmatrix * dest, const gsl_spmatrix * src); +int gsl_spmatrix_csr (gsl_spmatrix * dest, const gsl_spmatrix * src); +gsl_spmatrix * gsl_spmatrix_compress (const gsl_spmatrix * src, const int sptype); +gsl_spmatrix * gsl_spmatrix_compcol (const gsl_spmatrix * src); +gsl_spmatrix * gsl_spmatrix_ccs (const gsl_spmatrix * src); +gsl_spmatrix * gsl_spmatrix_crs (const gsl_spmatrix * src); + +/* copy */ + +int gsl_spmatrix_memcpy (gsl_spmatrix * dest, const gsl_spmatrix * src); + +/* file I/O */ + +int gsl_spmatrix_fprintf (FILE * stream, const gsl_spmatrix * m, const char * format); +gsl_spmatrix * gsl_spmatrix_fscanf (FILE * stream); +int gsl_spmatrix_fwrite (FILE * stream, const gsl_spmatrix * m); +int gsl_spmatrix_fread (FILE * stream, gsl_spmatrix * m); + +/* get/set */ + +double gsl_spmatrix_get (const gsl_spmatrix * m, const size_t i, const size_t j); +int gsl_spmatrix_set (gsl_spmatrix * m, const size_t i, const size_t j, const double x); +double * gsl_spmatrix_ptr (const gsl_spmatrix * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_minmax (const gsl_spmatrix * m, double * min_out, double * max_out); +int gsl_spmatrix_min_index (const gsl_spmatrix * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_scale (gsl_spmatrix * m, const double x); +int gsl_spmatrix_scale_columns (gsl_spmatrix * m, const gsl_vector * x); +int gsl_spmatrix_scale_rows (gsl_spmatrix * m, const gsl_vector * x); +int gsl_spmatrix_add (gsl_spmatrix * c, const gsl_spmatrix * a, const gsl_spmatrix * b); +int gsl_spmatrix_dense_add (gsl_matrix * a, const gsl_spmatrix * b); +int gsl_spmatrix_dense_sub (gsl_matrix * a, const gsl_spmatrix * b); +int gsl_spmatrix_d2sp (gsl_spmatrix * T, const gsl_matrix * A); +int gsl_spmatrix_sp2d (gsl_matrix * A, const gsl_spmatrix * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_add_to_dense (gsl_matrix * a, const gsl_spmatrix * b); + +#endif + +/* properties */ + +int gsl_spmatrix_equal (const gsl_spmatrix * a, const gsl_spmatrix * b); +double gsl_spmatrix_norm1 (const gsl_spmatrix * a); + +/* swap */ + +int gsl_spmatrix_transpose (gsl_spmatrix * m); +int gsl_spmatrix_transpose2 (gsl_spmatrix * m); +int gsl_spmatrix_transpose_memcpy (gsl_spmatrix * dest, const gsl_spmatrix * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_float.h new file mode 100644 index 0000000..3267983 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_float.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_float.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_FLOAT_H__ +#define __GSL_SPMATRIX_FLOAT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + float *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(float),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + float *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_float; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_float * gsl_spmatrix_float_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_float * gsl_spmatrix_float_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_float_free (gsl_spmatrix_float * m); +int gsl_spmatrix_float_realloc (const size_t nzmax, gsl_spmatrix_float * m); +size_t gsl_spmatrix_float_nnz (const gsl_spmatrix_float * m); +const char * gsl_spmatrix_float_type (const gsl_spmatrix_float * m); +int gsl_spmatrix_float_set_zero (gsl_spmatrix_float * m); +int gsl_spmatrix_float_tree_rebuild (gsl_spmatrix_float * m); + +/* compress */ + +int gsl_spmatrix_float_csc (gsl_spmatrix_float * dest, const gsl_spmatrix_float * src); +int gsl_spmatrix_float_csr (gsl_spmatrix_float * dest, const gsl_spmatrix_float * src); +gsl_spmatrix_float * gsl_spmatrix_float_compress (const gsl_spmatrix_float * src, const int sptype); +gsl_spmatrix_float * gsl_spmatrix_float_compcol (const gsl_spmatrix_float * src); +gsl_spmatrix_float * gsl_spmatrix_float_ccs (const gsl_spmatrix_float * src); +gsl_spmatrix_float * gsl_spmatrix_float_crs (const gsl_spmatrix_float * src); + +/* copy */ + +int gsl_spmatrix_float_memcpy (gsl_spmatrix_float * dest, const gsl_spmatrix_float * src); + +/* file I/O */ + +int gsl_spmatrix_float_fprintf (FILE * stream, const gsl_spmatrix_float * m, const char * format); +gsl_spmatrix_float * gsl_spmatrix_float_fscanf (FILE * stream); +int gsl_spmatrix_float_fwrite (FILE * stream, const gsl_spmatrix_float * m); +int gsl_spmatrix_float_fread (FILE * stream, gsl_spmatrix_float * m); + +/* get/set */ + +float gsl_spmatrix_float_get (const gsl_spmatrix_float * m, const size_t i, const size_t j); +int gsl_spmatrix_float_set (gsl_spmatrix_float * m, const size_t i, const size_t j, const float x); +float * gsl_spmatrix_float_ptr (const gsl_spmatrix_float * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_float_minmax (const gsl_spmatrix_float * m, float * min_out, float * max_out); +int gsl_spmatrix_float_min_index (const gsl_spmatrix_float * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_float_scale (gsl_spmatrix_float * m, const float x); +int gsl_spmatrix_float_scale_columns (gsl_spmatrix_float * m, const gsl_vector_float * x); +int gsl_spmatrix_float_scale_rows (gsl_spmatrix_float * m, const gsl_vector_float * x); +int gsl_spmatrix_float_add (gsl_spmatrix_float * c, const gsl_spmatrix_float * a, const gsl_spmatrix_float * b); +int gsl_spmatrix_float_dense_add (gsl_matrix_float * a, const gsl_spmatrix_float * b); +int gsl_spmatrix_float_dense_sub (gsl_matrix_float * a, const gsl_spmatrix_float * b); +int gsl_spmatrix_float_d2sp (gsl_spmatrix_float * T, const gsl_matrix_float * A); +int gsl_spmatrix_float_sp2d (gsl_matrix_float * A, const gsl_spmatrix_float * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_float_add_to_dense (gsl_matrix_float * a, const gsl_spmatrix_float * b); + +#endif + +/* properties */ + +int gsl_spmatrix_float_equal (const gsl_spmatrix_float * a, const gsl_spmatrix_float * b); +float gsl_spmatrix_float_norm1 (const gsl_spmatrix_float * a); + +/* swap */ + +int gsl_spmatrix_float_transpose (gsl_spmatrix_float * m); +int gsl_spmatrix_float_transpose2 (gsl_spmatrix_float * m); +int gsl_spmatrix_float_transpose_memcpy (gsl_spmatrix_float * dest, const gsl_spmatrix_float * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_int.h new file mode 100644 index 0000000..7855cd0 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_int.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_int.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_INT_H__ +#define __GSL_SPMATRIX_INT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + int *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(int),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + int *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_int; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_int * gsl_spmatrix_int_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_int * gsl_spmatrix_int_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_int_free (gsl_spmatrix_int * m); +int gsl_spmatrix_int_realloc (const size_t nzmax, gsl_spmatrix_int * m); +size_t gsl_spmatrix_int_nnz (const gsl_spmatrix_int * m); +const char * gsl_spmatrix_int_type (const gsl_spmatrix_int * m); +int gsl_spmatrix_int_set_zero (gsl_spmatrix_int * m); +int gsl_spmatrix_int_tree_rebuild (gsl_spmatrix_int * m); + +/* compress */ + +int gsl_spmatrix_int_csc (gsl_spmatrix_int * dest, const gsl_spmatrix_int * src); +int gsl_spmatrix_int_csr (gsl_spmatrix_int * dest, const gsl_spmatrix_int * src); +gsl_spmatrix_int * gsl_spmatrix_int_compress (const gsl_spmatrix_int * src, const int sptype); +gsl_spmatrix_int * gsl_spmatrix_int_compcol (const gsl_spmatrix_int * src); +gsl_spmatrix_int * gsl_spmatrix_int_ccs (const gsl_spmatrix_int * src); +gsl_spmatrix_int * gsl_spmatrix_int_crs (const gsl_spmatrix_int * src); + +/* copy */ + +int gsl_spmatrix_int_memcpy (gsl_spmatrix_int * dest, const gsl_spmatrix_int * src); + +/* file I/O */ + +int gsl_spmatrix_int_fprintf (FILE * stream, const gsl_spmatrix_int * m, const char * format); +gsl_spmatrix_int * gsl_spmatrix_int_fscanf (FILE * stream); +int gsl_spmatrix_int_fwrite (FILE * stream, const gsl_spmatrix_int * m); +int gsl_spmatrix_int_fread (FILE * stream, gsl_spmatrix_int * m); + +/* get/set */ + +int gsl_spmatrix_int_get (const gsl_spmatrix_int * m, const size_t i, const size_t j); +int gsl_spmatrix_int_set (gsl_spmatrix_int * m, const size_t i, const size_t j, const int x); +int * gsl_spmatrix_int_ptr (const gsl_spmatrix_int * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_int_minmax (const gsl_spmatrix_int * m, int * min_out, int * max_out); +int gsl_spmatrix_int_min_index (const gsl_spmatrix_int * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_int_scale (gsl_spmatrix_int * m, const int x); +int gsl_spmatrix_int_scale_columns (gsl_spmatrix_int * m, const gsl_vector_int * x); +int gsl_spmatrix_int_scale_rows (gsl_spmatrix_int * m, const gsl_vector_int * x); +int gsl_spmatrix_int_add (gsl_spmatrix_int * c, const gsl_spmatrix_int * a, const gsl_spmatrix_int * b); +int gsl_spmatrix_int_dense_add (gsl_matrix_int * a, const gsl_spmatrix_int * b); +int gsl_spmatrix_int_dense_sub (gsl_matrix_int * a, const gsl_spmatrix_int * b); +int gsl_spmatrix_int_d2sp (gsl_spmatrix_int * T, const gsl_matrix_int * A); +int gsl_spmatrix_int_sp2d (gsl_matrix_int * A, const gsl_spmatrix_int * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_int_add_to_dense (gsl_matrix_int * a, const gsl_spmatrix_int * b); + +#endif + +/* properties */ + +int gsl_spmatrix_int_equal (const gsl_spmatrix_int * a, const gsl_spmatrix_int * b); +int gsl_spmatrix_int_norm1 (const gsl_spmatrix_int * a); + +/* swap */ + +int gsl_spmatrix_int_transpose (gsl_spmatrix_int * m); +int gsl_spmatrix_int_transpose2 (gsl_spmatrix_int * m); +int gsl_spmatrix_int_transpose_memcpy (gsl_spmatrix_int * dest, const gsl_spmatrix_int * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long.h new file mode 100644 index 0000000..a37196b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_long.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_LONG_H__ +#define __GSL_SPMATRIX_LONG_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + long *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(long),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + long *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_long; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_long * gsl_spmatrix_long_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_long * gsl_spmatrix_long_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_long_free (gsl_spmatrix_long * m); +int gsl_spmatrix_long_realloc (const size_t nzmax, gsl_spmatrix_long * m); +size_t gsl_spmatrix_long_nnz (const gsl_spmatrix_long * m); +const char * gsl_spmatrix_long_type (const gsl_spmatrix_long * m); +int gsl_spmatrix_long_set_zero (gsl_spmatrix_long * m); +int gsl_spmatrix_long_tree_rebuild (gsl_spmatrix_long * m); + +/* compress */ + +int gsl_spmatrix_long_csc (gsl_spmatrix_long * dest, const gsl_spmatrix_long * src); +int gsl_spmatrix_long_csr (gsl_spmatrix_long * dest, const gsl_spmatrix_long * src); +gsl_spmatrix_long * gsl_spmatrix_long_compress (const gsl_spmatrix_long * src, const int sptype); +gsl_spmatrix_long * gsl_spmatrix_long_compcol (const gsl_spmatrix_long * src); +gsl_spmatrix_long * gsl_spmatrix_long_ccs (const gsl_spmatrix_long * src); +gsl_spmatrix_long * gsl_spmatrix_long_crs (const gsl_spmatrix_long * src); + +/* copy */ + +int gsl_spmatrix_long_memcpy (gsl_spmatrix_long * dest, const gsl_spmatrix_long * src); + +/* file I/O */ + +int gsl_spmatrix_long_fprintf (FILE * stream, const gsl_spmatrix_long * m, const char * format); +gsl_spmatrix_long * gsl_spmatrix_long_fscanf (FILE * stream); +int gsl_spmatrix_long_fwrite (FILE * stream, const gsl_spmatrix_long * m); +int gsl_spmatrix_long_fread (FILE * stream, gsl_spmatrix_long * m); + +/* get/set */ + +long gsl_spmatrix_long_get (const gsl_spmatrix_long * m, const size_t i, const size_t j); +int gsl_spmatrix_long_set (gsl_spmatrix_long * m, const size_t i, const size_t j, const long x); +long * gsl_spmatrix_long_ptr (const gsl_spmatrix_long * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_long_minmax (const gsl_spmatrix_long * m, long * min_out, long * max_out); +int gsl_spmatrix_long_min_index (const gsl_spmatrix_long * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_long_scale (gsl_spmatrix_long * m, const long x); +int gsl_spmatrix_long_scale_columns (gsl_spmatrix_long * m, const gsl_vector_long * x); +int gsl_spmatrix_long_scale_rows (gsl_spmatrix_long * m, const gsl_vector_long * x); +int gsl_spmatrix_long_add (gsl_spmatrix_long * c, const gsl_spmatrix_long * a, const gsl_spmatrix_long * b); +int gsl_spmatrix_long_dense_add (gsl_matrix_long * a, const gsl_spmatrix_long * b); +int gsl_spmatrix_long_dense_sub (gsl_matrix_long * a, const gsl_spmatrix_long * b); +int gsl_spmatrix_long_d2sp (gsl_spmatrix_long * T, const gsl_matrix_long * A); +int gsl_spmatrix_long_sp2d (gsl_matrix_long * A, const gsl_spmatrix_long * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_long_add_to_dense (gsl_matrix_long * a, const gsl_spmatrix_long * b); + +#endif + +/* properties */ + +int gsl_spmatrix_long_equal (const gsl_spmatrix_long * a, const gsl_spmatrix_long * b); +long gsl_spmatrix_long_norm1 (const gsl_spmatrix_long * a); + +/* swap */ + +int gsl_spmatrix_long_transpose (gsl_spmatrix_long * m); +int gsl_spmatrix_long_transpose2 (gsl_spmatrix_long * m); +int gsl_spmatrix_long_transpose_memcpy (gsl_spmatrix_long * dest, const gsl_spmatrix_long * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long_double.h new file mode 100644 index 0000000..bed06d3 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_long_double.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_long_double.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_LONG_DOUBLE_H__ +#define __GSL_SPMATRIX_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + long double *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(long double),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + long double *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_long_double; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_long_double * gsl_spmatrix_long_double_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_long_double_free (gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_realloc (const size_t nzmax, gsl_spmatrix_long_double * m); +size_t gsl_spmatrix_long_double_nnz (const gsl_spmatrix_long_double * m); +const char * gsl_spmatrix_long_double_type (const gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_set_zero (gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_tree_rebuild (gsl_spmatrix_long_double * m); + +/* compress */ + +int gsl_spmatrix_long_double_csc (gsl_spmatrix_long_double * dest, const gsl_spmatrix_long_double * src); +int gsl_spmatrix_long_double_csr (gsl_spmatrix_long_double * dest, const gsl_spmatrix_long_double * src); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_compress (const gsl_spmatrix_long_double * src, const int sptype); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_compcol (const gsl_spmatrix_long_double * src); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_ccs (const gsl_spmatrix_long_double * src); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_crs (const gsl_spmatrix_long_double * src); + +/* copy */ + +int gsl_spmatrix_long_double_memcpy (gsl_spmatrix_long_double * dest, const gsl_spmatrix_long_double * src); + +/* file I/O */ + +int gsl_spmatrix_long_double_fprintf (FILE * stream, const gsl_spmatrix_long_double * m, const char * format); +gsl_spmatrix_long_double * gsl_spmatrix_long_double_fscanf (FILE * stream); +int gsl_spmatrix_long_double_fwrite (FILE * stream, const gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_fread (FILE * stream, gsl_spmatrix_long_double * m); + +/* get/set */ + +long double gsl_spmatrix_long_double_get (const gsl_spmatrix_long_double * m, const size_t i, const size_t j); +int gsl_spmatrix_long_double_set (gsl_spmatrix_long_double * m, const size_t i, const size_t j, const long double x); +long double * gsl_spmatrix_long_double_ptr (const gsl_spmatrix_long_double * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_long_double_minmax (const gsl_spmatrix_long_double * m, long double * min_out, long double * max_out); +int gsl_spmatrix_long_double_min_index (const gsl_spmatrix_long_double * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_long_double_scale (gsl_spmatrix_long_double * m, const long double x); +int gsl_spmatrix_long_double_scale_columns (gsl_spmatrix_long_double * m, const gsl_vector_long_double * x); +int gsl_spmatrix_long_double_scale_rows (gsl_spmatrix_long_double * m, const gsl_vector_long_double * x); +int gsl_spmatrix_long_double_add (gsl_spmatrix_long_double * c, const gsl_spmatrix_long_double * a, const gsl_spmatrix_long_double * b); +int gsl_spmatrix_long_double_dense_add (gsl_matrix_long_double * a, const gsl_spmatrix_long_double * b); +int gsl_spmatrix_long_double_dense_sub (gsl_matrix_long_double * a, const gsl_spmatrix_long_double * b); +int gsl_spmatrix_long_double_d2sp (gsl_spmatrix_long_double * T, const gsl_matrix_long_double * A); +int gsl_spmatrix_long_double_sp2d (gsl_matrix_long_double * A, const gsl_spmatrix_long_double * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_long_double_add_to_dense (gsl_matrix_long_double * a, const gsl_spmatrix_long_double * b); + +#endif + +/* properties */ + +int gsl_spmatrix_long_double_equal (const gsl_spmatrix_long_double * a, const gsl_spmatrix_long_double * b); +long double gsl_spmatrix_long_double_norm1 (const gsl_spmatrix_long_double * a); + +/* swap */ + +int gsl_spmatrix_long_double_transpose (gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_transpose2 (gsl_spmatrix_long_double * m); +int gsl_spmatrix_long_double_transpose_memcpy (gsl_spmatrix_long_double * dest, const gsl_spmatrix_long_double * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_short.h new file mode 100644 index 0000000..6fbd0d5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_short.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_short.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_SHORT_H__ +#define __GSL_SPMATRIX_SHORT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + short *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(short),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + short *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_short; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_short * gsl_spmatrix_short_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_short * gsl_spmatrix_short_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_short_free (gsl_spmatrix_short * m); +int gsl_spmatrix_short_realloc (const size_t nzmax, gsl_spmatrix_short * m); +size_t gsl_spmatrix_short_nnz (const gsl_spmatrix_short * m); +const char * gsl_spmatrix_short_type (const gsl_spmatrix_short * m); +int gsl_spmatrix_short_set_zero (gsl_spmatrix_short * m); +int gsl_spmatrix_short_tree_rebuild (gsl_spmatrix_short * m); + +/* compress */ + +int gsl_spmatrix_short_csc (gsl_spmatrix_short * dest, const gsl_spmatrix_short * src); +int gsl_spmatrix_short_csr (gsl_spmatrix_short * dest, const gsl_spmatrix_short * src); +gsl_spmatrix_short * gsl_spmatrix_short_compress (const gsl_spmatrix_short * src, const int sptype); +gsl_spmatrix_short * gsl_spmatrix_short_compcol (const gsl_spmatrix_short * src); +gsl_spmatrix_short * gsl_spmatrix_short_ccs (const gsl_spmatrix_short * src); +gsl_spmatrix_short * gsl_spmatrix_short_crs (const gsl_spmatrix_short * src); + +/* copy */ + +int gsl_spmatrix_short_memcpy (gsl_spmatrix_short * dest, const gsl_spmatrix_short * src); + +/* file I/O */ + +int gsl_spmatrix_short_fprintf (FILE * stream, const gsl_spmatrix_short * m, const char * format); +gsl_spmatrix_short * gsl_spmatrix_short_fscanf (FILE * stream); +int gsl_spmatrix_short_fwrite (FILE * stream, const gsl_spmatrix_short * m); +int gsl_spmatrix_short_fread (FILE * stream, gsl_spmatrix_short * m); + +/* get/set */ + +short gsl_spmatrix_short_get (const gsl_spmatrix_short * m, const size_t i, const size_t j); +int gsl_spmatrix_short_set (gsl_spmatrix_short * m, const size_t i, const size_t j, const short x); +short * gsl_spmatrix_short_ptr (const gsl_spmatrix_short * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_short_minmax (const gsl_spmatrix_short * m, short * min_out, short * max_out); +int gsl_spmatrix_short_min_index (const gsl_spmatrix_short * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_short_scale (gsl_spmatrix_short * m, const short x); +int gsl_spmatrix_short_scale_columns (gsl_spmatrix_short * m, const gsl_vector_short * x); +int gsl_spmatrix_short_scale_rows (gsl_spmatrix_short * m, const gsl_vector_short * x); +int gsl_spmatrix_short_add (gsl_spmatrix_short * c, const gsl_spmatrix_short * a, const gsl_spmatrix_short * b); +int gsl_spmatrix_short_dense_add (gsl_matrix_short * a, const gsl_spmatrix_short * b); +int gsl_spmatrix_short_dense_sub (gsl_matrix_short * a, const gsl_spmatrix_short * b); +int gsl_spmatrix_short_d2sp (gsl_spmatrix_short * T, const gsl_matrix_short * A); +int gsl_spmatrix_short_sp2d (gsl_matrix_short * A, const gsl_spmatrix_short * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_short_add_to_dense (gsl_matrix_short * a, const gsl_spmatrix_short * b); + +#endif + +/* properties */ + +int gsl_spmatrix_short_equal (const gsl_spmatrix_short * a, const gsl_spmatrix_short * b); +short gsl_spmatrix_short_norm1 (const gsl_spmatrix_short * a); + +/* swap */ + +int gsl_spmatrix_short_transpose (gsl_spmatrix_short * m); +int gsl_spmatrix_short_transpose2 (gsl_spmatrix_short * m); +int gsl_spmatrix_short_transpose_memcpy (gsl_spmatrix_short * dest, const gsl_spmatrix_short * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uchar.h new file mode 100644 index 0000000..66bf39b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uchar.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_uchar.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_UCHAR_H__ +#define __GSL_SPMATRIX_UCHAR_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + unsigned char *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(unsigned char),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + unsigned char *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_uchar; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_uchar * gsl_spmatrix_uchar_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_uchar_free (gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_realloc (const size_t nzmax, gsl_spmatrix_uchar * m); +size_t gsl_spmatrix_uchar_nnz (const gsl_spmatrix_uchar * m); +const char * gsl_spmatrix_uchar_type (const gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_set_zero (gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_tree_rebuild (gsl_spmatrix_uchar * m); + +/* compress */ + +int gsl_spmatrix_uchar_csc (gsl_spmatrix_uchar * dest, const gsl_spmatrix_uchar * src); +int gsl_spmatrix_uchar_csr (gsl_spmatrix_uchar * dest, const gsl_spmatrix_uchar * src); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_compress (const gsl_spmatrix_uchar * src, const int sptype); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_compcol (const gsl_spmatrix_uchar * src); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_ccs (const gsl_spmatrix_uchar * src); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_crs (const gsl_spmatrix_uchar * src); + +/* copy */ + +int gsl_spmatrix_uchar_memcpy (gsl_spmatrix_uchar * dest, const gsl_spmatrix_uchar * src); + +/* file I/O */ + +int gsl_spmatrix_uchar_fprintf (FILE * stream, const gsl_spmatrix_uchar * m, const char * format); +gsl_spmatrix_uchar * gsl_spmatrix_uchar_fscanf (FILE * stream); +int gsl_spmatrix_uchar_fwrite (FILE * stream, const gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_fread (FILE * stream, gsl_spmatrix_uchar * m); + +/* get/set */ + +unsigned char gsl_spmatrix_uchar_get (const gsl_spmatrix_uchar * m, const size_t i, const size_t j); +int gsl_spmatrix_uchar_set (gsl_spmatrix_uchar * m, const size_t i, const size_t j, const unsigned char x); +unsigned char * gsl_spmatrix_uchar_ptr (const gsl_spmatrix_uchar * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_uchar_minmax (const gsl_spmatrix_uchar * m, unsigned char * min_out, unsigned char * max_out); +int gsl_spmatrix_uchar_min_index (const gsl_spmatrix_uchar * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_uchar_scale (gsl_spmatrix_uchar * m, const unsigned char x); +int gsl_spmatrix_uchar_scale_columns (gsl_spmatrix_uchar * m, const gsl_vector_uchar * x); +int gsl_spmatrix_uchar_scale_rows (gsl_spmatrix_uchar * m, const gsl_vector_uchar * x); +int gsl_spmatrix_uchar_add (gsl_spmatrix_uchar * c, const gsl_spmatrix_uchar * a, const gsl_spmatrix_uchar * b); +int gsl_spmatrix_uchar_dense_add (gsl_matrix_uchar * a, const gsl_spmatrix_uchar * b); +int gsl_spmatrix_uchar_dense_sub (gsl_matrix_uchar * a, const gsl_spmatrix_uchar * b); +int gsl_spmatrix_uchar_d2sp (gsl_spmatrix_uchar * T, const gsl_matrix_uchar * A); +int gsl_spmatrix_uchar_sp2d (gsl_matrix_uchar * A, const gsl_spmatrix_uchar * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_uchar_add_to_dense (gsl_matrix_uchar * a, const gsl_spmatrix_uchar * b); + +#endif + +/* properties */ + +int gsl_spmatrix_uchar_equal (const gsl_spmatrix_uchar * a, const gsl_spmatrix_uchar * b); +unsigned char gsl_spmatrix_uchar_norm1 (const gsl_spmatrix_uchar * a); + +/* swap */ + +int gsl_spmatrix_uchar_transpose (gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_transpose2 (gsl_spmatrix_uchar * m); +int gsl_spmatrix_uchar_transpose_memcpy (gsl_spmatrix_uchar * dest, const gsl_spmatrix_uchar * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uint.h new file mode 100644 index 0000000..b7ad555 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_uint.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_uint.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_UINT_H__ +#define __GSL_SPMATRIX_UINT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + unsigned int *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(unsigned int),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + unsigned int *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_uint; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_uint * gsl_spmatrix_uint_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_uint * gsl_spmatrix_uint_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_uint_free (gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_realloc (const size_t nzmax, gsl_spmatrix_uint * m); +size_t gsl_spmatrix_uint_nnz (const gsl_spmatrix_uint * m); +const char * gsl_spmatrix_uint_type (const gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_set_zero (gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_tree_rebuild (gsl_spmatrix_uint * m); + +/* compress */ + +int gsl_spmatrix_uint_csc (gsl_spmatrix_uint * dest, const gsl_spmatrix_uint * src); +int gsl_spmatrix_uint_csr (gsl_spmatrix_uint * dest, const gsl_spmatrix_uint * src); +gsl_spmatrix_uint * gsl_spmatrix_uint_compress (const gsl_spmatrix_uint * src, const int sptype); +gsl_spmatrix_uint * gsl_spmatrix_uint_compcol (const gsl_spmatrix_uint * src); +gsl_spmatrix_uint * gsl_spmatrix_uint_ccs (const gsl_spmatrix_uint * src); +gsl_spmatrix_uint * gsl_spmatrix_uint_crs (const gsl_spmatrix_uint * src); + +/* copy */ + +int gsl_spmatrix_uint_memcpy (gsl_spmatrix_uint * dest, const gsl_spmatrix_uint * src); + +/* file I/O */ + +int gsl_spmatrix_uint_fprintf (FILE * stream, const gsl_spmatrix_uint * m, const char * format); +gsl_spmatrix_uint * gsl_spmatrix_uint_fscanf (FILE * stream); +int gsl_spmatrix_uint_fwrite (FILE * stream, const gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_fread (FILE * stream, gsl_spmatrix_uint * m); + +/* get/set */ + +unsigned int gsl_spmatrix_uint_get (const gsl_spmatrix_uint * m, const size_t i, const size_t j); +int gsl_spmatrix_uint_set (gsl_spmatrix_uint * m, const size_t i, const size_t j, const unsigned int x); +unsigned int * gsl_spmatrix_uint_ptr (const gsl_spmatrix_uint * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_uint_minmax (const gsl_spmatrix_uint * m, unsigned int * min_out, unsigned int * max_out); +int gsl_spmatrix_uint_min_index (const gsl_spmatrix_uint * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_uint_scale (gsl_spmatrix_uint * m, const unsigned int x); +int gsl_spmatrix_uint_scale_columns (gsl_spmatrix_uint * m, const gsl_vector_uint * x); +int gsl_spmatrix_uint_scale_rows (gsl_spmatrix_uint * m, const gsl_vector_uint * x); +int gsl_spmatrix_uint_add (gsl_spmatrix_uint * c, const gsl_spmatrix_uint * a, const gsl_spmatrix_uint * b); +int gsl_spmatrix_uint_dense_add (gsl_matrix_uint * a, const gsl_spmatrix_uint * b); +int gsl_spmatrix_uint_dense_sub (gsl_matrix_uint * a, const gsl_spmatrix_uint * b); +int gsl_spmatrix_uint_d2sp (gsl_spmatrix_uint * T, const gsl_matrix_uint * A); +int gsl_spmatrix_uint_sp2d (gsl_matrix_uint * A, const gsl_spmatrix_uint * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_uint_add_to_dense (gsl_matrix_uint * a, const gsl_spmatrix_uint * b); + +#endif + +/* properties */ + +int gsl_spmatrix_uint_equal (const gsl_spmatrix_uint * a, const gsl_spmatrix_uint * b); +unsigned int gsl_spmatrix_uint_norm1 (const gsl_spmatrix_uint * a); + +/* swap */ + +int gsl_spmatrix_uint_transpose (gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_transpose2 (gsl_spmatrix_uint * m); +int gsl_spmatrix_uint_transpose_memcpy (gsl_spmatrix_uint * dest, const gsl_spmatrix_uint * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ulong.h new file mode 100644 index 0000000..498d731 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ulong.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_ulong.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_ULONG_H__ +#define __GSL_SPMATRIX_ULONG_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + unsigned long *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(unsigned long),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + unsigned long *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_ulong; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_ulong * gsl_spmatrix_ulong_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_ulong_free (gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_realloc (const size_t nzmax, gsl_spmatrix_ulong * m); +size_t gsl_spmatrix_ulong_nnz (const gsl_spmatrix_ulong * m); +const char * gsl_spmatrix_ulong_type (const gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_set_zero (gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_tree_rebuild (gsl_spmatrix_ulong * m); + +/* compress */ + +int gsl_spmatrix_ulong_csc (gsl_spmatrix_ulong * dest, const gsl_spmatrix_ulong * src); +int gsl_spmatrix_ulong_csr (gsl_spmatrix_ulong * dest, const gsl_spmatrix_ulong * src); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_compress (const gsl_spmatrix_ulong * src, const int sptype); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_compcol (const gsl_spmatrix_ulong * src); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_ccs (const gsl_spmatrix_ulong * src); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_crs (const gsl_spmatrix_ulong * src); + +/* copy */ + +int gsl_spmatrix_ulong_memcpy (gsl_spmatrix_ulong * dest, const gsl_spmatrix_ulong * src); + +/* file I/O */ + +int gsl_spmatrix_ulong_fprintf (FILE * stream, const gsl_spmatrix_ulong * m, const char * format); +gsl_spmatrix_ulong * gsl_spmatrix_ulong_fscanf (FILE * stream); +int gsl_spmatrix_ulong_fwrite (FILE * stream, const gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_fread (FILE * stream, gsl_spmatrix_ulong * m); + +/* get/set */ + +unsigned long gsl_spmatrix_ulong_get (const gsl_spmatrix_ulong * m, const size_t i, const size_t j); +int gsl_spmatrix_ulong_set (gsl_spmatrix_ulong * m, const size_t i, const size_t j, const unsigned long x); +unsigned long * gsl_spmatrix_ulong_ptr (const gsl_spmatrix_ulong * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_ulong_minmax (const gsl_spmatrix_ulong * m, unsigned long * min_out, unsigned long * max_out); +int gsl_spmatrix_ulong_min_index (const gsl_spmatrix_ulong * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_ulong_scale (gsl_spmatrix_ulong * m, const unsigned long x); +int gsl_spmatrix_ulong_scale_columns (gsl_spmatrix_ulong * m, const gsl_vector_ulong * x); +int gsl_spmatrix_ulong_scale_rows (gsl_spmatrix_ulong * m, const gsl_vector_ulong * x); +int gsl_spmatrix_ulong_add (gsl_spmatrix_ulong * c, const gsl_spmatrix_ulong * a, const gsl_spmatrix_ulong * b); +int gsl_spmatrix_ulong_dense_add (gsl_matrix_ulong * a, const gsl_spmatrix_ulong * b); +int gsl_spmatrix_ulong_dense_sub (gsl_matrix_ulong * a, const gsl_spmatrix_ulong * b); +int gsl_spmatrix_ulong_d2sp (gsl_spmatrix_ulong * T, const gsl_matrix_ulong * A); +int gsl_spmatrix_ulong_sp2d (gsl_matrix_ulong * A, const gsl_spmatrix_ulong * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_ulong_add_to_dense (gsl_matrix_ulong * a, const gsl_spmatrix_ulong * b); + +#endif + +/* properties */ + +int gsl_spmatrix_ulong_equal (const gsl_spmatrix_ulong * a, const gsl_spmatrix_ulong * b); +unsigned long gsl_spmatrix_ulong_norm1 (const gsl_spmatrix_ulong * a); + +/* swap */ + +int gsl_spmatrix_ulong_transpose (gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_transpose2 (gsl_spmatrix_ulong * m); +int gsl_spmatrix_ulong_transpose_memcpy (gsl_spmatrix_ulong * dest, const gsl_spmatrix_ulong * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ushort.h new file mode 100644 index 0000000..56d5435 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_spmatrix_ushort.h @@ -0,0 +1,185 @@ +/* spmatrix/gsl_spmatrix_ushort.h + * + * Copyright (C) 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SPMATRIX_USHORT_H__ +#define __GSL_SPMATRIX_USHORT_H__ + +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* + * COO format: + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * j = A->p[n] + * + * Compressed column format (CSC): + * + * If data[n] = A_{ij}, then: + * i = A->i[n] + * A->p[j] <= n < A->p[j+1] + * so that column j is stored in + * [ data[p[j]], data[p[j] + 1], ..., data[p[j+1] - 1] ] + * + * Compressed row format (CSR): + * + * If data[n] = A_{ij}, then: + * j = A->i[n] + * A->p[i] <= n < A->p[i+1] + * so that row i is stored in + * [ data[p[i]], data[p[i] + 1], ..., data[p[i+1] - 1] ] + */ + +typedef struct +{ + size_t size1; /* number of rows */ + size_t size2; /* number of columns */ + + /* i (size nzmax) contains: + * + * COO/CSC: row indices + * CSR: column indices + */ + int *i; + + unsigned short *data; /* matrix elements of size nzmax */ + + /* + * COO: p[n] = column number of element data[n] + * CSC: p[j] = index in data of first non-zero element in column j + * CSR: p[i] = index in data of first non-zero element in row i + */ + int *p; + + size_t nzmax; /* maximum number of matrix elements */ + size_t nz; /* number of non-zero values in matrix */ + + gsl_bst_workspace *tree; /* binary tree structure */ + gsl_spmatrix_pool *pool; /* memory pool for binary tree nodes */ + size_t node_size; /* size of individual tree node in bytes */ + + /* + * workspace of size MAX(size1,size2)*MAX(sizeof(unsigned short),sizeof(int)) + * used in various routines + */ + union + { + void *work_void; + int *work_int; + unsigned short *work_atomic; + } work; + + int sptype; /* sparse storage type */ + size_t spflags; /* GSL_SPMATRIX_FLG_xxx */ +} gsl_spmatrix_ushort; + +/* + * Prototypes + */ + +/* allocation / initialization */ + +gsl_spmatrix_ushort * gsl_spmatrix_ushort_alloc (const size_t n1, const size_t n2); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_alloc_nzmax (const size_t n1, const size_t n2, + const size_t nzmax, const int sptype); +void gsl_spmatrix_ushort_free (gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_realloc (const size_t nzmax, gsl_spmatrix_ushort * m); +size_t gsl_spmatrix_ushort_nnz (const gsl_spmatrix_ushort * m); +const char * gsl_spmatrix_ushort_type (const gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_set_zero (gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_tree_rebuild (gsl_spmatrix_ushort * m); + +/* compress */ + +int gsl_spmatrix_ushort_csc (gsl_spmatrix_ushort * dest, const gsl_spmatrix_ushort * src); +int gsl_spmatrix_ushort_csr (gsl_spmatrix_ushort * dest, const gsl_spmatrix_ushort * src); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_compress (const gsl_spmatrix_ushort * src, const int sptype); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_compcol (const gsl_spmatrix_ushort * src); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_ccs (const gsl_spmatrix_ushort * src); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_crs (const gsl_spmatrix_ushort * src); + +/* copy */ + +int gsl_spmatrix_ushort_memcpy (gsl_spmatrix_ushort * dest, const gsl_spmatrix_ushort * src); + +/* file I/O */ + +int gsl_spmatrix_ushort_fprintf (FILE * stream, const gsl_spmatrix_ushort * m, const char * format); +gsl_spmatrix_ushort * gsl_spmatrix_ushort_fscanf (FILE * stream); +int gsl_spmatrix_ushort_fwrite (FILE * stream, const gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_fread (FILE * stream, gsl_spmatrix_ushort * m); + +/* get/set */ + +unsigned short gsl_spmatrix_ushort_get (const gsl_spmatrix_ushort * m, const size_t i, const size_t j); +int gsl_spmatrix_ushort_set (gsl_spmatrix_ushort * m, const size_t i, const size_t j, const unsigned short x); +unsigned short * gsl_spmatrix_ushort_ptr (const gsl_spmatrix_ushort * m, const size_t i, const size_t j); + +/* minmax */ + +int gsl_spmatrix_ushort_minmax (const gsl_spmatrix_ushort * m, unsigned short * min_out, unsigned short * max_out); +int gsl_spmatrix_ushort_min_index (const gsl_spmatrix_ushort * m, size_t * imin_out, size_t * jmin_out); + +/* operations */ + +int gsl_spmatrix_ushort_scale (gsl_spmatrix_ushort * m, const unsigned short x); +int gsl_spmatrix_ushort_scale_columns (gsl_spmatrix_ushort * m, const gsl_vector_ushort * x); +int gsl_spmatrix_ushort_scale_rows (gsl_spmatrix_ushort * m, const gsl_vector_ushort * x); +int gsl_spmatrix_ushort_add (gsl_spmatrix_ushort * c, const gsl_spmatrix_ushort * a, const gsl_spmatrix_ushort * b); +int gsl_spmatrix_ushort_dense_add (gsl_matrix_ushort * a, const gsl_spmatrix_ushort * b); +int gsl_spmatrix_ushort_dense_sub (gsl_matrix_ushort * a, const gsl_spmatrix_ushort * b); +int gsl_spmatrix_ushort_d2sp (gsl_spmatrix_ushort * T, const gsl_matrix_ushort * A); +int gsl_spmatrix_ushort_sp2d (gsl_matrix_ushort * A, const gsl_spmatrix_ushort * S); + +#ifndef GSL_DISABLE_DEPRECATED + +int gsl_spmatrix_ushort_add_to_dense (gsl_matrix_ushort * a, const gsl_spmatrix_ushort * b); + +#endif + +/* properties */ + +int gsl_spmatrix_ushort_equal (const gsl_spmatrix_ushort * a, const gsl_spmatrix_ushort * b); +unsigned short gsl_spmatrix_ushort_norm1 (const gsl_spmatrix_ushort * a); + +/* swap */ + +int gsl_spmatrix_ushort_transpose (gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_transpose2 (gsl_spmatrix_ushort * m); +int gsl_spmatrix_ushort_transpose_memcpy (gsl_spmatrix_ushort * dest, const gsl_spmatrix_ushort * src); + +__END_DECLS + +#endif /* __GSL_SPMATRIX_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics.h new file mode 100644 index 0000000..9fb414f --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics.h @@ -0,0 +1,20 @@ +#ifndef __GSL_STATISTICS_H__ +#define __GSL_STATISTICS_H__ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#endif /* __GSL_STATISTICS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_char.h new file mode 100644 index 0000000..c77d4c4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_char.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_CHAR_H__ +#define __GSL_STATISTICS_CHAR_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_char_mean (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_variance (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_sd (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_variance_with_fixed_mean (const char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_char_sd_with_fixed_mean (const char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_char_tss (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_tss_m (const char data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_char_absdev (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_skew (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_kurtosis (const char data[], const size_t stride, const size_t n); +double gsl_stats_char_lag1_autocorrelation (const char data[], const size_t stride, const size_t n); + +double gsl_stats_char_covariance (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n); +double gsl_stats_char_correlation (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n); +double gsl_stats_char_spearman (const char data1[], const size_t stride1, const char data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_char_variance_m (const char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_char_sd_m (const char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_char_absdev_m (const char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_char_skew_m_sd (const char data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_char_kurtosis_m_sd (const char data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_char_lag1_autocorrelation_m (const char data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_char_covariance_m (const char data1[], const size_t stride1,const char data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_char_pvariance (const char data1[], const size_t stride1, const size_t n1, const char data2[], const size_t stride2, const size_t n2); +double gsl_stats_char_ttest (const char data1[], const size_t stride1, const size_t n1, const char data2[], const size_t stride2, const size_t n2); + +char gsl_stats_char_max (const char data[], const size_t stride, const size_t n); +char gsl_stats_char_min (const char data[], const size_t stride, const size_t n); +void gsl_stats_char_minmax (char * min, char * max, const char data[], const size_t stride, const size_t n); + +size_t gsl_stats_char_max_index (const char data[], const size_t stride, const size_t n); +size_t gsl_stats_char_min_index (const char data[], const size_t stride, const size_t n); +void gsl_stats_char_minmax_index (size_t * min_index, size_t * max_index, const char data[], const size_t stride, const size_t n); + +char gsl_stats_char_select(char data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_char_median_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_char_median (char sorted_data[], const size_t stride, const size_t n); +double gsl_stats_char_quantile_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_char_trmean_from_sorted_data (const double trim, const char sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_char_gastwirth_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_char_mad0(const char data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_char_mad(const char data[], const size_t stride, const size_t n, double work[]); + +char gsl_stats_char_Sn0_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, char work[]) ; +double gsl_stats_char_Sn_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, char work[]) ; + +char gsl_stats_char_Qn0_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, char work[], int work_int[]) ; +double gsl_stats_char_Qn_from_sorted_data (const char sorted_data[], const size_t stride, const size_t n, char work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_CHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_double.h new file mode 100644 index 0000000..9969472 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_double.h @@ -0,0 +1,116 @@ +/* statistics/gsl_statistics_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_DOUBLE_H__ +#define __GSL_STATISTICS_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_mean (const double data[], const size_t stride, const size_t n); +double gsl_stats_variance (const double data[], const size_t stride, const size_t n); +double gsl_stats_sd (const double data[], const size_t stride, const size_t n); +double gsl_stats_variance_with_fixed_mean (const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_sd_with_fixed_mean (const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_tss (const double data[], const size_t stride, const size_t n); +double gsl_stats_tss_m (const double data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_absdev (const double data[], const size_t stride, const size_t n); +double gsl_stats_skew (const double data[], const size_t stride, const size_t n); +double gsl_stats_kurtosis (const double data[], const size_t stride, const size_t n); +double gsl_stats_lag1_autocorrelation (const double data[], const size_t stride, const size_t n); + +double gsl_stats_covariance (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n); +double gsl_stats_correlation (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n); +double gsl_stats_spearman (const double data1[], const size_t stride1, const double data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_variance_m (const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_sd_m (const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_absdev_m (const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_skew_m_sd (const double data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_kurtosis_m_sd (const double data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_lag1_autocorrelation_m (const double data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_covariance_m (const double data1[], const size_t stride1,const double data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + +/* DEFINED FOR FLOATING POINT TYPES ONLY */ + +double gsl_stats_wmean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wvariance (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wsd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wvariance_with_fixed_mean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_wsd_with_fixed_mean (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_wtss (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wtss_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_wabsdev (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wskew (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); +double gsl_stats_wkurtosis (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n); + +double gsl_stats_wvariance_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_wsd_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_wabsdev_m (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_wskew_m_sd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean, const double wsd); +double gsl_stats_wkurtosis_m_sd (const double w[], const size_t wstride, const double data[], const size_t stride, const size_t n, const double wmean, const double wsd); + +/* END OF FLOATING POINT TYPES */ + +double gsl_stats_pvariance (const double data1[], const size_t stride1, const size_t n1, const double data2[], const size_t stride2, const size_t n2); +double gsl_stats_ttest (const double data1[], const size_t stride1, const size_t n1, const double data2[], const size_t stride2, const size_t n2); + +double gsl_stats_max (const double data[], const size_t stride, const size_t n); +double gsl_stats_min (const double data[], const size_t stride, const size_t n); +void gsl_stats_minmax (double * min, double * max, const double data[], const size_t stride, const size_t n); + +size_t gsl_stats_max_index (const double data[], const size_t stride, const size_t n); +size_t gsl_stats_min_index (const double data[], const size_t stride, const size_t n); +void gsl_stats_minmax_index (size_t * min_index, size_t * max_index, const double data[], const size_t stride, const size_t n); + +double gsl_stats_select(double data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_median_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_median (double sorted_data[], const size_t stride, const size_t n); +double gsl_stats_quantile_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_trmean_from_sorted_data (const double trim, const double sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_gastwirth_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_mad0(const double data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_mad(const double data[], const size_t stride, const size_t n, double work[]); + +double gsl_stats_Sn0_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, double work[]) ; +double gsl_stats_Sn_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, double work[]) ; + +double gsl_stats_Qn0_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, double work[], int work_int[]) ; +double gsl_stats_Qn_from_sorted_data (const double sorted_data[], const size_t stride, const size_t n, double work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_float.h new file mode 100644 index 0000000..fa61a4d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_float.h @@ -0,0 +1,116 @@ +/* statistics/gsl_statistics_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_FLOAT_H__ +#define __GSL_STATISTICS_FLOAT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_float_mean (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_variance (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_sd (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_variance_with_fixed_mean (const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_sd_with_fixed_mean (const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_tss (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_tss_m (const float data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_float_absdev (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_skew (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_kurtosis (const float data[], const size_t stride, const size_t n); +double gsl_stats_float_lag1_autocorrelation (const float data[], const size_t stride, const size_t n); + +double gsl_stats_float_covariance (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n); +double gsl_stats_float_correlation (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n); +double gsl_stats_float_spearman (const float data1[], const size_t stride1, const float data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_float_variance_m (const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_sd_m (const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_absdev_m (const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_skew_m_sd (const float data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_float_kurtosis_m_sd (const float data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_float_lag1_autocorrelation_m (const float data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_float_covariance_m (const float data1[], const size_t stride1,const float data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + +/* DEFINED FOR FLOATING POINT TYPES ONLY */ + +double gsl_stats_float_wmean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wvariance (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wsd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wvariance_with_fixed_mean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_wsd_with_fixed_mean (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_float_wtss (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wtss_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_float_wabsdev (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wskew (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); +double gsl_stats_float_wkurtosis (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n); + +double gsl_stats_float_wvariance_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_float_wsd_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_float_wabsdev_m (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_float_wskew_m_sd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean, const double wsd); +double gsl_stats_float_wkurtosis_m_sd (const float w[], const size_t wstride, const float data[], const size_t stride, const size_t n, const double wmean, const double wsd); + +/* END OF FLOATING POINT TYPES */ + +double gsl_stats_float_pvariance (const float data1[], const size_t stride1, const size_t n1, const float data2[], const size_t stride2, const size_t n2); +double gsl_stats_float_ttest (const float data1[], const size_t stride1, const size_t n1, const float data2[], const size_t stride2, const size_t n2); + +float gsl_stats_float_max (const float data[], const size_t stride, const size_t n); +float gsl_stats_float_min (const float data[], const size_t stride, const size_t n); +void gsl_stats_float_minmax (float * min, float * max, const float data[], const size_t stride, const size_t n); + +size_t gsl_stats_float_max_index (const float data[], const size_t stride, const size_t n); +size_t gsl_stats_float_min_index (const float data[], const size_t stride, const size_t n); +void gsl_stats_float_minmax_index (size_t * min_index, size_t * max_index, const float data[], const size_t stride, const size_t n); + +float gsl_stats_float_select(float data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_float_median_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_float_median (float sorted_data[], const size_t stride, const size_t n); +double gsl_stats_float_quantile_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_float_trmean_from_sorted_data (const double trim, const float sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_float_gastwirth_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_float_mad0(const float data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_float_mad(const float data[], const size_t stride, const size_t n, double work[]); + +float gsl_stats_float_Sn0_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, float work[]) ; +double gsl_stats_float_Sn_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, float work[]) ; + +float gsl_stats_float_Qn0_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, float work[], int work_int[]) ; +double gsl_stats_float_Qn_from_sorted_data (const float sorted_data[], const size_t stride, const size_t n, float work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_int.h new file mode 100644 index 0000000..1d02b3a --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_int.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_INT_H__ +#define __GSL_STATISTICS_INT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_int_mean (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_variance (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_sd (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_variance_with_fixed_mean (const int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_int_sd_with_fixed_mean (const int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_int_tss (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_tss_m (const int data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_int_absdev (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_skew (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_kurtosis (const int data[], const size_t stride, const size_t n); +double gsl_stats_int_lag1_autocorrelation (const int data[], const size_t stride, const size_t n); + +double gsl_stats_int_covariance (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n); +double gsl_stats_int_correlation (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n); +double gsl_stats_int_spearman (const int data1[], const size_t stride1, const int data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_int_variance_m (const int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_int_sd_m (const int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_int_absdev_m (const int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_int_skew_m_sd (const int data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_int_kurtosis_m_sd (const int data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_int_lag1_autocorrelation_m (const int data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_int_covariance_m (const int data1[], const size_t stride1,const int data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_int_pvariance (const int data1[], const size_t stride1, const size_t n1, const int data2[], const size_t stride2, const size_t n2); +double gsl_stats_int_ttest (const int data1[], const size_t stride1, const size_t n1, const int data2[], const size_t stride2, const size_t n2); + +int gsl_stats_int_max (const int data[], const size_t stride, const size_t n); +int gsl_stats_int_min (const int data[], const size_t stride, const size_t n); +void gsl_stats_int_minmax (int * min, int * max, const int data[], const size_t stride, const size_t n); + +size_t gsl_stats_int_max_index (const int data[], const size_t stride, const size_t n); +size_t gsl_stats_int_min_index (const int data[], const size_t stride, const size_t n); +void gsl_stats_int_minmax_index (size_t * min_index, size_t * max_index, const int data[], const size_t stride, const size_t n); + +int gsl_stats_int_select(int data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_int_median_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_int_median (int sorted_data[], const size_t stride, const size_t n); +double gsl_stats_int_quantile_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_int_trmean_from_sorted_data (const double trim, const int sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_int_gastwirth_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_int_mad0(const int data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_int_mad(const int data[], const size_t stride, const size_t n, double work[]); + +int gsl_stats_int_Sn0_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, int work[]) ; +double gsl_stats_int_Sn_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, int work[]) ; + +int gsl_stats_int_Qn0_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, int work[], int work_int[]) ; +double gsl_stats_int_Qn_from_sorted_data (const int sorted_data[], const size_t stride, const size_t n, int work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_INT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long.h new file mode 100644 index 0000000..5bc4bbd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_LONG_H__ +#define __GSL_STATISTICS_LONG_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_long_mean (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_variance (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_sd (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_variance_with_fixed_mean (const long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_sd_with_fixed_mean (const long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_tss (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_tss_m (const long data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_long_absdev (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_skew (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_kurtosis (const long data[], const size_t stride, const size_t n); +double gsl_stats_long_lag1_autocorrelation (const long data[], const size_t stride, const size_t n); + +double gsl_stats_long_covariance (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n); +double gsl_stats_long_correlation (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n); +double gsl_stats_long_spearman (const long data1[], const size_t stride1, const long data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_long_variance_m (const long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_sd_m (const long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_absdev_m (const long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_skew_m_sd (const long data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_long_kurtosis_m_sd (const long data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_long_lag1_autocorrelation_m (const long data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_long_covariance_m (const long data1[], const size_t stride1,const long data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_long_pvariance (const long data1[], const size_t stride1, const size_t n1, const long data2[], const size_t stride2, const size_t n2); +double gsl_stats_long_ttest (const long data1[], const size_t stride1, const size_t n1, const long data2[], const size_t stride2, const size_t n2); + +long gsl_stats_long_max (const long data[], const size_t stride, const size_t n); +long gsl_stats_long_min (const long data[], const size_t stride, const size_t n); +void gsl_stats_long_minmax (long * min, long * max, const long data[], const size_t stride, const size_t n); + +size_t gsl_stats_long_max_index (const long data[], const size_t stride, const size_t n); +size_t gsl_stats_long_min_index (const long data[], const size_t stride, const size_t n); +void gsl_stats_long_minmax_index (size_t * min_index, size_t * max_index, const long data[], const size_t stride, const size_t n); + +long gsl_stats_long_select(long data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_long_median_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_long_median (long sorted_data[], const size_t stride, const size_t n); +double gsl_stats_long_quantile_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_long_trmean_from_sorted_data (const double trim, const long sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_long_gastwirth_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_long_mad0(const long data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_long_mad(const long data[], const size_t stride, const size_t n, double work[]); + +long gsl_stats_long_Sn0_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, long work[]) ; +double gsl_stats_long_Sn_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, long work[]) ; + +long gsl_stats_long_Qn0_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, long work[], int work_int[]) ; +double gsl_stats_long_Qn_from_sorted_data (const long sorted_data[], const size_t stride, const size_t n, long work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_LONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long_double.h new file mode 100644 index 0000000..6b38427 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_long_double.h @@ -0,0 +1,116 @@ +/* statistics/gsl_statistics_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_LONG_DOUBLE_H__ +#define __GSL_STATISTICS_LONG_DOUBLE_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_long_double_mean (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_variance (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_sd (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_variance_with_fixed_mean (const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_sd_with_fixed_mean (const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_tss (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_tss_m (const long double data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_long_double_absdev (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_skew (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_kurtosis (const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_lag1_autocorrelation (const long double data[], const size_t stride, const size_t n); + +double gsl_stats_long_double_covariance (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n); +double gsl_stats_long_double_correlation (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n); +double gsl_stats_long_double_spearman (const long double data1[], const size_t stride1, const long double data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_long_double_variance_m (const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_sd_m (const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_absdev_m (const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_skew_m_sd (const long double data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_long_double_kurtosis_m_sd (const long double data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_long_double_lag1_autocorrelation_m (const long double data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_long_double_covariance_m (const long double data1[], const size_t stride1,const long double data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + +/* DEFINED FOR FLOATING POINT TYPES ONLY */ + +double gsl_stats_long_double_wmean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wvariance (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wsd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wvariance_with_fixed_mean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_wsd_with_fixed_mean (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_long_double_wtss (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wtss_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_long_double_wabsdev (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wskew (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); +double gsl_stats_long_double_wkurtosis (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n); + +double gsl_stats_long_double_wvariance_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_long_double_wsd_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_long_double_wabsdev_m (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean); +double gsl_stats_long_double_wskew_m_sd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean, const double wsd); +double gsl_stats_long_double_wkurtosis_m_sd (const long double w[], const size_t wstride, const long double data[], const size_t stride, const size_t n, const double wmean, const double wsd); + +/* END OF FLOATING POINT TYPES */ + +double gsl_stats_long_double_pvariance (const long double data1[], const size_t stride1, const size_t n1, const long double data2[], const size_t stride2, const size_t n2); +double gsl_stats_long_double_ttest (const long double data1[], const size_t stride1, const size_t n1, const long double data2[], const size_t stride2, const size_t n2); + +long double gsl_stats_long_double_max (const long double data[], const size_t stride, const size_t n); +long double gsl_stats_long_double_min (const long double data[], const size_t stride, const size_t n); +void gsl_stats_long_double_minmax (long double * min, long double * max, const long double data[], const size_t stride, const size_t n); + +size_t gsl_stats_long_double_max_index (const long double data[], const size_t stride, const size_t n); +size_t gsl_stats_long_double_min_index (const long double data[], const size_t stride, const size_t n); +void gsl_stats_long_double_minmax_index (size_t * min_index, size_t * max_index, const long double data[], const size_t stride, const size_t n); + +long double gsl_stats_long_double_select(long double data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_long_double_median_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_long_double_median (long double sorted_data[], const size_t stride, const size_t n); +double gsl_stats_long_double_quantile_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_long_double_trmean_from_sorted_data (const double trim, const long double sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_long_double_gastwirth_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_long_double_mad0(const long double data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_long_double_mad(const long double data[], const size_t stride, const size_t n, double work[]); + +long double gsl_stats_long_double_Sn0_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, long double work[]) ; +double gsl_stats_long_double_Sn_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, long double work[]) ; + +long double gsl_stats_long_double_Qn0_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, long double work[], int work_int[]) ; +double gsl_stats_long_double_Qn_from_sorted_data (const long double sorted_data[], const size_t stride, const size_t n, long double work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_short.h new file mode 100644 index 0000000..8ecacee --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_short.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_SHORT_H__ +#define __GSL_STATISTICS_SHORT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_short_mean (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_variance (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_sd (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_variance_with_fixed_mean (const short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_short_sd_with_fixed_mean (const short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_short_tss (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_tss_m (const short data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_short_absdev (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_skew (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_kurtosis (const short data[], const size_t stride, const size_t n); +double gsl_stats_short_lag1_autocorrelation (const short data[], const size_t stride, const size_t n); + +double gsl_stats_short_covariance (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n); +double gsl_stats_short_correlation (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n); +double gsl_stats_short_spearman (const short data1[], const size_t stride1, const short data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_short_variance_m (const short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_short_sd_m (const short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_short_absdev_m (const short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_short_skew_m_sd (const short data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_short_kurtosis_m_sd (const short data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_short_lag1_autocorrelation_m (const short data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_short_covariance_m (const short data1[], const size_t stride1,const short data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_short_pvariance (const short data1[], const size_t stride1, const size_t n1, const short data2[], const size_t stride2, const size_t n2); +double gsl_stats_short_ttest (const short data1[], const size_t stride1, const size_t n1, const short data2[], const size_t stride2, const size_t n2); + +short gsl_stats_short_max (const short data[], const size_t stride, const size_t n); +short gsl_stats_short_min (const short data[], const size_t stride, const size_t n); +void gsl_stats_short_minmax (short * min, short * max, const short data[], const size_t stride, const size_t n); + +size_t gsl_stats_short_max_index (const short data[], const size_t stride, const size_t n); +size_t gsl_stats_short_min_index (const short data[], const size_t stride, const size_t n); +void gsl_stats_short_minmax_index (size_t * min_index, size_t * max_index, const short data[], const size_t stride, const size_t n); + +short gsl_stats_short_select(short data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_short_median_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_short_median (short sorted_data[], const size_t stride, const size_t n); +double gsl_stats_short_quantile_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_short_trmean_from_sorted_data (const double trim, const short sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_short_gastwirth_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_short_mad0(const short data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_short_mad(const short data[], const size_t stride, const size_t n, double work[]); + +short gsl_stats_short_Sn0_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, short work[]) ; +double gsl_stats_short_Sn_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, short work[]) ; + +short gsl_stats_short_Qn0_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, short work[], int work_int[]) ; +double gsl_stats_short_Qn_from_sorted_data (const short sorted_data[], const size_t stride, const size_t n, short work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_SHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uchar.h new file mode 100644 index 0000000..e5f549b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uchar.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_UCHAR_H__ +#define __GSL_STATISTICS_UCHAR_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_uchar_mean (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_variance (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_sd (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_variance_with_fixed_mean (const unsigned char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uchar_sd_with_fixed_mean (const unsigned char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uchar_tss (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_tss_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_uchar_absdev (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_skew (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_kurtosis (const unsigned char data[], const size_t stride, const size_t n); +double gsl_stats_uchar_lag1_autocorrelation (const unsigned char data[], const size_t stride, const size_t n); + +double gsl_stats_uchar_covariance (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n); +double gsl_stats_uchar_correlation (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n); +double gsl_stats_uchar_spearman (const unsigned char data1[], const size_t stride1, const unsigned char data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_uchar_variance_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uchar_sd_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uchar_absdev_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uchar_skew_m_sd (const unsigned char data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_uchar_kurtosis_m_sd (const unsigned char data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_uchar_lag1_autocorrelation_m (const unsigned char data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_uchar_covariance_m (const unsigned char data1[], const size_t stride1,const unsigned char data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_uchar_pvariance (const unsigned char data1[], const size_t stride1, const size_t n1, const unsigned char data2[], const size_t stride2, const size_t n2); +double gsl_stats_uchar_ttest (const unsigned char data1[], const size_t stride1, const size_t n1, const unsigned char data2[], const size_t stride2, const size_t n2); + +unsigned char gsl_stats_uchar_max (const unsigned char data[], const size_t stride, const size_t n); +unsigned char gsl_stats_uchar_min (const unsigned char data[], const size_t stride, const size_t n); +void gsl_stats_uchar_minmax (unsigned char * min, unsigned char * max, const unsigned char data[], const size_t stride, const size_t n); + +size_t gsl_stats_uchar_max_index (const unsigned char data[], const size_t stride, const size_t n); +size_t gsl_stats_uchar_min_index (const unsigned char data[], const size_t stride, const size_t n); +void gsl_stats_uchar_minmax_index (size_t * min_index, size_t * max_index, const unsigned char data[], const size_t stride, const size_t n); + +unsigned char gsl_stats_uchar_select(unsigned char data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_uchar_median_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_uchar_median (unsigned char sorted_data[], const size_t stride, const size_t n); +double gsl_stats_uchar_quantile_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_uchar_trmean_from_sorted_data (const double trim, const unsigned char sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_uchar_gastwirth_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_uchar_mad0(const unsigned char data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_uchar_mad(const unsigned char data[], const size_t stride, const size_t n, double work[]); + +unsigned char gsl_stats_uchar_Sn0_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, unsigned char work[]) ; +double gsl_stats_uchar_Sn_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, unsigned char work[]) ; + +unsigned char gsl_stats_uchar_Qn0_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, unsigned char work[], int work_int[]) ; +double gsl_stats_uchar_Qn_from_sorted_data (const unsigned char sorted_data[], const size_t stride, const size_t n, unsigned char work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_UCHAR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uint.h new file mode 100644 index 0000000..fca9e7d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_uint.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_UINT_H__ +#define __GSL_STATISTICS_UINT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_uint_mean (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_variance (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_sd (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_variance_with_fixed_mean (const unsigned int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uint_sd_with_fixed_mean (const unsigned int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uint_tss (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_tss_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_uint_absdev (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_skew (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_kurtosis (const unsigned int data[], const size_t stride, const size_t n); +double gsl_stats_uint_lag1_autocorrelation (const unsigned int data[], const size_t stride, const size_t n); + +double gsl_stats_uint_covariance (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n); +double gsl_stats_uint_correlation (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n); +double gsl_stats_uint_spearman (const unsigned int data1[], const size_t stride1, const unsigned int data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_uint_variance_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uint_sd_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uint_absdev_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_uint_skew_m_sd (const unsigned int data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_uint_kurtosis_m_sd (const unsigned int data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_uint_lag1_autocorrelation_m (const unsigned int data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_uint_covariance_m (const unsigned int data1[], const size_t stride1,const unsigned int data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_uint_pvariance (const unsigned int data1[], const size_t stride1, const size_t n1, const unsigned int data2[], const size_t stride2, const size_t n2); +double gsl_stats_uint_ttest (const unsigned int data1[], const size_t stride1, const size_t n1, const unsigned int data2[], const size_t stride2, const size_t n2); + +unsigned int gsl_stats_uint_max (const unsigned int data[], const size_t stride, const size_t n); +unsigned int gsl_stats_uint_min (const unsigned int data[], const size_t stride, const size_t n); +void gsl_stats_uint_minmax (unsigned int * min, unsigned int * max, const unsigned int data[], const size_t stride, const size_t n); + +size_t gsl_stats_uint_max_index (const unsigned int data[], const size_t stride, const size_t n); +size_t gsl_stats_uint_min_index (const unsigned int data[], const size_t stride, const size_t n); +void gsl_stats_uint_minmax_index (size_t * min_index, size_t * max_index, const unsigned int data[], const size_t stride, const size_t n); + +unsigned int gsl_stats_uint_select(unsigned int data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_uint_median_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_uint_median (unsigned int sorted_data[], const size_t stride, const size_t n); +double gsl_stats_uint_quantile_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_uint_trmean_from_sorted_data (const double trim, const unsigned int sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_uint_gastwirth_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_uint_mad0(const unsigned int data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_uint_mad(const unsigned int data[], const size_t stride, const size_t n, double work[]); + +unsigned int gsl_stats_uint_Sn0_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, unsigned int work[]) ; +double gsl_stats_uint_Sn_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, unsigned int work[]) ; + +unsigned int gsl_stats_uint_Qn0_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, unsigned int work[], int work_int[]) ; +double gsl_stats_uint_Qn_from_sorted_data (const unsigned int sorted_data[], const size_t stride, const size_t n, unsigned int work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_UINT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ulong.h new file mode 100644 index 0000000..2957fd1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ulong.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_ULONG_H__ +#define __GSL_STATISTICS_ULONG_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_ulong_mean (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_variance (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_sd (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_variance_with_fixed_mean (const unsigned long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ulong_sd_with_fixed_mean (const unsigned long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ulong_tss (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_tss_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_ulong_absdev (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_skew (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_kurtosis (const unsigned long data[], const size_t stride, const size_t n); +double gsl_stats_ulong_lag1_autocorrelation (const unsigned long data[], const size_t stride, const size_t n); + +double gsl_stats_ulong_covariance (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n); +double gsl_stats_ulong_correlation (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n); +double gsl_stats_ulong_spearman (const unsigned long data1[], const size_t stride1, const unsigned long data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_ulong_variance_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ulong_sd_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ulong_absdev_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ulong_skew_m_sd (const unsigned long data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_ulong_kurtosis_m_sd (const unsigned long data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_ulong_lag1_autocorrelation_m (const unsigned long data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_ulong_covariance_m (const unsigned long data1[], const size_t stride1,const unsigned long data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_ulong_pvariance (const unsigned long data1[], const size_t stride1, const size_t n1, const unsigned long data2[], const size_t stride2, const size_t n2); +double gsl_stats_ulong_ttest (const unsigned long data1[], const size_t stride1, const size_t n1, const unsigned long data2[], const size_t stride2, const size_t n2); + +unsigned long gsl_stats_ulong_max (const unsigned long data[], const size_t stride, const size_t n); +unsigned long gsl_stats_ulong_min (const unsigned long data[], const size_t stride, const size_t n); +void gsl_stats_ulong_minmax (unsigned long * min, unsigned long * max, const unsigned long data[], const size_t stride, const size_t n); + +size_t gsl_stats_ulong_max_index (const unsigned long data[], const size_t stride, const size_t n); +size_t gsl_stats_ulong_min_index (const unsigned long data[], const size_t stride, const size_t n); +void gsl_stats_ulong_minmax_index (size_t * min_index, size_t * max_index, const unsigned long data[], const size_t stride, const size_t n); + +unsigned long gsl_stats_ulong_select(unsigned long data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_ulong_median_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_ulong_median (unsigned long sorted_data[], const size_t stride, const size_t n); +double gsl_stats_ulong_quantile_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_ulong_trmean_from_sorted_data (const double trim, const unsigned long sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_ulong_gastwirth_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_ulong_mad0(const unsigned long data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_ulong_mad(const unsigned long data[], const size_t stride, const size_t n, double work[]); + +unsigned long gsl_stats_ulong_Sn0_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, unsigned long work[]) ; +double gsl_stats_ulong_Sn_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, unsigned long work[]) ; + +unsigned long gsl_stats_ulong_Qn0_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, unsigned long work[], int work_int[]) ; +double gsl_stats_ulong_Qn_from_sorted_data (const unsigned long sorted_data[], const size_t stride, const size_t n, unsigned long work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_ULONG_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ushort.h new file mode 100644 index 0000000..7625f5d --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_statistics_ushort.h @@ -0,0 +1,96 @@ +/* statistics/gsl_statistics_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jim Davies, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_STATISTICS_USHORT_H__ +#define __GSL_STATISTICS_USHORT_H__ + +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_stats_ushort_mean (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_variance (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_sd (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_variance_with_fixed_mean (const unsigned short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ushort_sd_with_fixed_mean (const unsigned short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ushort_tss (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_tss_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_ushort_absdev (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_skew (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_kurtosis (const unsigned short data[], const size_t stride, const size_t n); +double gsl_stats_ushort_lag1_autocorrelation (const unsigned short data[], const size_t stride, const size_t n); + +double gsl_stats_ushort_covariance (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n); +double gsl_stats_ushort_correlation (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n); +double gsl_stats_ushort_spearman (const unsigned short data1[], const size_t stride1, const unsigned short data2[], const size_t stride2, const size_t n, double work[]); + +double gsl_stats_ushort_variance_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ushort_sd_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ushort_absdev_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); +double gsl_stats_ushort_skew_m_sd (const unsigned short data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_ushort_kurtosis_m_sd (const unsigned short data[], const size_t stride, const size_t n, const double mean, const double sd); +double gsl_stats_ushort_lag1_autocorrelation_m (const unsigned short data[], const size_t stride, const size_t n, const double mean); + +double gsl_stats_ushort_covariance_m (const unsigned short data1[], const size_t stride1,const unsigned short data2[], const size_t stride2, const size_t n, const double mean1, const double mean2); + + +double gsl_stats_ushort_pvariance (const unsigned short data1[], const size_t stride1, const size_t n1, const unsigned short data2[], const size_t stride2, const size_t n2); +double gsl_stats_ushort_ttest (const unsigned short data1[], const size_t stride1, const size_t n1, const unsigned short data2[], const size_t stride2, const size_t n2); + +unsigned short gsl_stats_ushort_max (const unsigned short data[], const size_t stride, const size_t n); +unsigned short gsl_stats_ushort_min (const unsigned short data[], const size_t stride, const size_t n); +void gsl_stats_ushort_minmax (unsigned short * min, unsigned short * max, const unsigned short data[], const size_t stride, const size_t n); + +size_t gsl_stats_ushort_max_index (const unsigned short data[], const size_t stride, const size_t n); +size_t gsl_stats_ushort_min_index (const unsigned short data[], const size_t stride, const size_t n); +void gsl_stats_ushort_minmax_index (size_t * min_index, size_t * max_index, const unsigned short data[], const size_t stride, const size_t n); + +unsigned short gsl_stats_ushort_select(unsigned short data[], const size_t stride, const size_t n, const size_t k); + +double gsl_stats_ushort_median_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_ushort_median (unsigned short sorted_data[], const size_t stride, const size_t n); +double gsl_stats_ushort_quantile_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, const double f) ; + +double gsl_stats_ushort_trmean_from_sorted_data (const double trim, const unsigned short sorted_data[], const size_t stride, const size_t n) ; +double gsl_stats_ushort_gastwirth_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n) ; + +double gsl_stats_ushort_mad0(const unsigned short data[], const size_t stride, const size_t n, double work[]); +double gsl_stats_ushort_mad(const unsigned short data[], const size_t stride, const size_t n, double work[]); + +unsigned short gsl_stats_ushort_Sn0_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, unsigned short work[]) ; +double gsl_stats_ushort_Sn_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, unsigned short work[]) ; + +unsigned short gsl_stats_ushort_Qn0_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, unsigned short work[], int work_int[]) ; +double gsl_stats_ushort_Qn_from_sorted_data (const unsigned short sorted_data[], const size_t stride, const size_t n, unsigned short work[], int work_int[]) ; + +__END_DECLS + +#endif /* __GSL_STATISTICS_USHORT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sum.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sum.h new file mode 100644 index 0000000..d9c4da8 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sum.h @@ -0,0 +1,162 @@ +/* sum/gsl_sum.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Author: G. Jungman */ + + +#ifndef __GSL_SUM_H__ +#define __GSL_SUM_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Workspace for Levin U Transform with error estimation, + * + * size = number of terms the workspace can handle + * sum_plain = simple sum of series + * q_num = backward diagonal of numerator; length = size + * q_den = backward diagonal of denominator; length = size + * dq_num = table of numerator derivatives; length = size**2 + * dq_den = table of denominator derivatives; length = size**2 + * dsum = derivative of sum wrt term i; length = size + */ + +typedef struct +{ + size_t size; + size_t i; /* position in array */ + size_t terms_used; /* number of calls */ + double sum_plain; + double *q_num; + double *q_den; + double *dq_num; + double *dq_den; + double *dsum; +} +gsl_sum_levin_u_workspace; + +gsl_sum_levin_u_workspace *gsl_sum_levin_u_alloc (size_t n); +void gsl_sum_levin_u_free (gsl_sum_levin_u_workspace * w); + +/* Basic Levin-u acceleration method. + * + * array = array of series elements + * n = size of array + * sum_accel = result of summation acceleration + * err = estimated error + * + * See [Fessler et al., ACM TOMS 9, 346 (1983) and TOMS-602] + */ + +int gsl_sum_levin_u_accel (const double *array, + const size_t n, + gsl_sum_levin_u_workspace * w, + double *sum_accel, double *abserr); + +/* Basic Levin-u acceleration method with constraints on the terms + * used, + * + * array = array of series elements + * n = size of array + * min_terms = minimum number of terms to sum + * max_terms = maximum number of terms to sum + * sum_accel = result of summation acceleration + * err = estimated error + * + * See [Fessler et al., ACM TOMS 9, 346 (1983) and TOMS-602] + */ + +int gsl_sum_levin_u_minmax (const double *array, + const size_t n, + const size_t min_terms, + const size_t max_terms, + gsl_sum_levin_u_workspace * w, + double *sum_accel, double *abserr); + +/* Basic Levin-u step w/o reference to the array of terms. + * We only need to specify the value of the current term + * to execute the step. See TOMS-745. + * + * sum = t0 + ... + t_{n-1} + term; term = t_{n} + * + * term = value of the series term to be added + * n = position of term in series (starting from 0) + * sum_accel = result of summation acceleration + * sum_plain = simple sum of series + */ + +int +gsl_sum_levin_u_step (const double term, + const size_t n, + const size_t nmax, + gsl_sum_levin_u_workspace * w, + double *sum_accel); + +/* The following functions perform the same calculation without + estimating the errors. They require O(N) storage instead of O(N^2). + This may be useful for summing many similar series where the size + of the error has already been estimated reliably and is not + expected to change. */ + +typedef struct +{ + size_t size; + size_t i; /* position in array */ + size_t terms_used; /* number of calls */ + double sum_plain; + double *q_num; + double *q_den; + double *dsum; +} +gsl_sum_levin_utrunc_workspace; + +gsl_sum_levin_utrunc_workspace *gsl_sum_levin_utrunc_alloc (size_t n); +void gsl_sum_levin_utrunc_free (gsl_sum_levin_utrunc_workspace * w); + +int gsl_sum_levin_utrunc_accel (const double *array, + const size_t n, + gsl_sum_levin_utrunc_workspace * w, + double *sum_accel, double *abserr_trunc); + +int gsl_sum_levin_utrunc_minmax (const double *array, + const size_t n, + const size_t min_terms, + const size_t max_terms, + gsl_sum_levin_utrunc_workspace * w, + double *sum_accel, double *abserr_trunc); + +int gsl_sum_levin_utrunc_step (const double term, + const size_t n, + gsl_sum_levin_utrunc_workspace * w, + double *sum_accel); + +__END_DECLS + +#endif /* __GSL_SUM_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_sys.h b/ChaosDataPlayer/GSL/include/gsl/gsl_sys.h new file mode 100644 index 0000000..25e1348 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_sys.h @@ -0,0 +1,63 @@ +/* sys/gsl_sys.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_SYS_H__ +#define __GSL_SYS_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +double gsl_log1p (const double x); +double gsl_expm1 (const double x); +double gsl_hypot (const double x, const double y); +double gsl_hypot3 (const double x, const double y, const double z); +double gsl_acosh (const double x); +double gsl_asinh (const double x); +double gsl_atanh (const double x); + +int gsl_isnan (const double x); +int gsl_isinf (const double x); +int gsl_finite (const double x); + +double gsl_nan (void); +double gsl_posinf (void); +double gsl_neginf (void); +double gsl_fdiv (const double x, const double y); + +double gsl_coerce_double (const double x); +float gsl_coerce_float (const float x); +long double gsl_coerce_long_double (const long double x); + +double gsl_ldexp(const double x, const int e); +double gsl_frexp(const double x, int * e); + +int gsl_fcmp (const double x1, const double x2, const double epsilon); + +__END_DECLS + +#endif /* __GSL_SYS_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_test.h b/ChaosDataPlayer/GSL/include/gsl/gsl_test.h new file mode 100644 index 0000000..bb86896 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_test.h @@ -0,0 +1,66 @@ +/* err/gsl_test.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_TEST_H__ +#define __GSL_TEST_H__ + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +void + gsl_test (int status, const char *test_description, ...); + +void +gsl_test_rel (double result, double expected, double relative_error, + const char *test_description, ...) ; + +void +gsl_test_abs (double result, double expected, double absolute_error, + const char *test_description, ...) ; + +void +gsl_test_factor (double result, double expected, double factor, + const char *test_description, ...) ; + +void +gsl_test_int (int result, int expected, const char *test_description, ...) ; + +void +gsl_test_str (const char * result, const char * expected, + const char *test_description, ...) ; + +void + gsl_test_verbose (int verbose) ; + +int + gsl_test_summary (void) ; + + +__END_DECLS + +#endif /* __GSL_TEST_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_types.h b/ChaosDataPlayer/GSL/include/gsl/gsl_types.h new file mode 100644 index 0000000..0330f55 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_types.h @@ -0,0 +1,41 @@ +/* gsl_types.h + * + * Copyright (C) 2001, 2007 Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_TYPES_H__ +#define __GSL_TYPES_H__ + +#ifndef GSL_VAR + +#ifdef WIN32 +# ifdef GSL_DLL +# ifdef DLL_EXPORT +# define GSL_VAR extern __declspec(dllexport) +# else +# define GSL_VAR extern __declspec(dllimport) +# endif +# else +# define GSL_VAR extern +# endif +#else +# define GSL_VAR extern +#endif + +#endif + +#endif /* __GSL_TYPES_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector.h new file mode 100644 index 0000000..cf762e4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector.h @@ -0,0 +1,25 @@ +#ifndef __GSL_VECTOR_H__ +#define __GSL_VECTOR_H__ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + + +#endif /* __GSL_VECTOR_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_char.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_char.h new file mode 100644 index 0000000..df903e4 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_char.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_char.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_CHAR_H__ +#define __GSL_VECTOR_CHAR_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + char *data; + gsl_block_char *block; + int owner; +} +gsl_vector_char; + +typedef struct +{ + gsl_vector_char vector; +} _gsl_vector_char_view; + +typedef _gsl_vector_char_view gsl_vector_char_view; + +typedef struct +{ + gsl_vector_char vector; +} _gsl_vector_char_const_view; + +typedef const _gsl_vector_char_const_view gsl_vector_char_const_view; + + +/* Allocation */ + +gsl_vector_char *gsl_vector_char_alloc (const size_t n); +gsl_vector_char *gsl_vector_char_calloc (const size_t n); + +gsl_vector_char *gsl_vector_char_alloc_from_block (gsl_block_char * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_char *gsl_vector_char_alloc_from_vector (gsl_vector_char * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_char_free (gsl_vector_char * v); + +/* Views */ + +_gsl_vector_char_view +gsl_vector_char_view_array (char *v, size_t n); + +_gsl_vector_char_view +gsl_vector_char_view_array_with_stride (char *base, + size_t stride, + size_t n); + +_gsl_vector_char_const_view +gsl_vector_char_const_view_array (const char *v, size_t n); + +_gsl_vector_char_const_view +gsl_vector_char_const_view_array_with_stride (const char *base, + size_t stride, + size_t n); + +_gsl_vector_char_view +gsl_vector_char_subvector (gsl_vector_char *v, + size_t i, + size_t n); + +_gsl_vector_char_view +gsl_vector_char_subvector_with_stride (gsl_vector_char *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_char_const_view +gsl_vector_char_const_subvector (const gsl_vector_char *v, + size_t i, + size_t n); + +_gsl_vector_char_const_view +gsl_vector_char_const_subvector_with_stride (const gsl_vector_char *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_char_set_zero (gsl_vector_char * v); +void gsl_vector_char_set_all (gsl_vector_char * v, char x); +int gsl_vector_char_set_basis (gsl_vector_char * v, size_t i); + +int gsl_vector_char_fread (FILE * stream, gsl_vector_char * v); +int gsl_vector_char_fwrite (FILE * stream, const gsl_vector_char * v); +int gsl_vector_char_fscanf (FILE * stream, gsl_vector_char * v); +int gsl_vector_char_fprintf (FILE * stream, const gsl_vector_char * v, + const char *format); + +int gsl_vector_char_memcpy (gsl_vector_char * dest, const gsl_vector_char * src); + +int gsl_vector_char_reverse (gsl_vector_char * v); + +int gsl_vector_char_swap (gsl_vector_char * v, gsl_vector_char * w); +int gsl_vector_char_swap_elements (gsl_vector_char * v, const size_t i, const size_t j); + +char gsl_vector_char_max (const gsl_vector_char * v); +char gsl_vector_char_min (const gsl_vector_char * v); +void gsl_vector_char_minmax (const gsl_vector_char * v, char * min_out, char * max_out); + +size_t gsl_vector_char_max_index (const gsl_vector_char * v); +size_t gsl_vector_char_min_index (const gsl_vector_char * v); +void gsl_vector_char_minmax_index (const gsl_vector_char * v, size_t * imin, size_t * imax); + +int gsl_vector_char_add (gsl_vector_char * a, const gsl_vector_char * b); +int gsl_vector_char_sub (gsl_vector_char * a, const gsl_vector_char * b); +int gsl_vector_char_mul (gsl_vector_char * a, const gsl_vector_char * b); +int gsl_vector_char_div (gsl_vector_char * a, const gsl_vector_char * b); +int gsl_vector_char_scale (gsl_vector_char * a, const char x); +int gsl_vector_char_add_constant (gsl_vector_char * a, const char x); +int gsl_vector_char_axpby (const char alpha, const gsl_vector_char * x, const char beta, gsl_vector_char * y); +char gsl_vector_char_sum (const gsl_vector_char * a); + +int gsl_vector_char_equal (const gsl_vector_char * u, + const gsl_vector_char * v); + +int gsl_vector_char_isnull (const gsl_vector_char * v); +int gsl_vector_char_ispos (const gsl_vector_char * v); +int gsl_vector_char_isneg (const gsl_vector_char * v); +int gsl_vector_char_isnonneg (const gsl_vector_char * v); + +INLINE_DECL char gsl_vector_char_get (const gsl_vector_char * v, const size_t i); +INLINE_DECL void gsl_vector_char_set (gsl_vector_char * v, const size_t i, char x); +INLINE_DECL char * gsl_vector_char_ptr (gsl_vector_char * v, const size_t i); +INLINE_DECL const char * gsl_vector_char_const_ptr (const gsl_vector_char * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +char +gsl_vector_char_get (const gsl_vector_char * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_char_set (gsl_vector_char * v, const size_t i, char x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +char * +gsl_vector_char_ptr (gsl_vector_char * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (char *) (v->data + i * v->stride); +} + +INLINE_FUN +const char * +gsl_vector_char_const_ptr (const gsl_vector_char * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const char *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_CHAR_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex.h new file mode 100644 index 0000000..e56d6a6 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex.h @@ -0,0 +1,17 @@ +#ifndef __GSL_VECTOR_COMPLEX_H__ +#define __GSL_VECTOR_COMPLEX_H__ + +#define GSL_VECTOR_REAL(z, i) ((z)->data[2*(i)*(z)->stride]) +#define GSL_VECTOR_IMAG(z, i) ((z)->data[2*(i)*(z)->stride + 1]) + +#if GSL_RANGE_CHECK +#define GSL_VECTOR_COMPLEX(zv, i) (((i) >= (zv)->size ? (gsl_error ("index out of range", __FILE__, __LINE__, GSL_EINVAL), 0):0 , *GSL_COMPLEX_AT((zv),(i)))) +#else +#define GSL_VECTOR_COMPLEX(zv, i) (*GSL_COMPLEX_AT((zv),(i))) +#endif + +#define GSL_COMPLEX_AT(zv,i) ((gsl_complex*)&((zv)->data[2*(i)*(zv)->stride])) +#define GSL_COMPLEX_FLOAT_AT(zv,i) ((gsl_complex_float*)&((zv)->data[2*(i)*(zv)->stride])) +#define GSL_COMPLEX_LONG_DOUBLE_AT(zv,i) ((gsl_complex_long_double*)&((zv)->data[2*(i)*(zv)->stride])) + +#endif /* __GSL_VECTOR_COMPLEX_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_double.h new file mode 100644 index 0000000..8d964bf --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_double.h @@ -0,0 +1,252 @@ +/* vector/gsl_vector_complex_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_COMPLEX_DOUBLE_H__ +#define __GSL_VECTOR_COMPLEX_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + double *data; + gsl_block_complex *block; + int owner; +} gsl_vector_complex; + +typedef struct +{ + gsl_vector_complex vector; +} _gsl_vector_complex_view; + +typedef _gsl_vector_complex_view gsl_vector_complex_view; + +typedef struct +{ + gsl_vector_complex vector; +} _gsl_vector_complex_const_view; + +typedef const _gsl_vector_complex_const_view gsl_vector_complex_const_view; + +/* Allocation */ + +gsl_vector_complex *gsl_vector_complex_alloc (const size_t n); +gsl_vector_complex *gsl_vector_complex_calloc (const size_t n); + +gsl_vector_complex * +gsl_vector_complex_alloc_from_block (gsl_block_complex * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_complex * +gsl_vector_complex_alloc_from_vector (gsl_vector_complex * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_complex_free (gsl_vector_complex * v); + +/* Views */ + +_gsl_vector_complex_view +gsl_vector_complex_view_array (double *base, + size_t n); + +_gsl_vector_complex_view +gsl_vector_complex_view_array_with_stride (double *base, + size_t stride, + size_t n); + +_gsl_vector_complex_const_view +gsl_vector_complex_const_view_array (const double *base, + size_t n); + +_gsl_vector_complex_const_view +gsl_vector_complex_const_view_array_with_stride (const double *base, + size_t stride, + size_t n); + +_gsl_vector_complex_view +gsl_vector_complex_subvector (gsl_vector_complex *base, + size_t i, + size_t n); + + +_gsl_vector_complex_view +gsl_vector_complex_subvector_with_stride (gsl_vector_complex *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_complex_const_view +gsl_vector_complex_const_subvector (const gsl_vector_complex *base, + size_t i, + size_t n); + + +_gsl_vector_complex_const_view +gsl_vector_complex_const_subvector_with_stride (const gsl_vector_complex *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_view +gsl_vector_complex_real (gsl_vector_complex *v); + +_gsl_vector_view +gsl_vector_complex_imag (gsl_vector_complex *v); + +_gsl_vector_const_view +gsl_vector_complex_const_real (const gsl_vector_complex *v); + +_gsl_vector_const_view +gsl_vector_complex_const_imag (const gsl_vector_complex *v); + + +/* Operations */ + +void gsl_vector_complex_set_zero (gsl_vector_complex * v); +void gsl_vector_complex_set_all (gsl_vector_complex * v, + gsl_complex z); +int gsl_vector_complex_set_basis (gsl_vector_complex * v, size_t i); + +int gsl_vector_complex_fread (FILE * stream, + gsl_vector_complex * v); +int gsl_vector_complex_fwrite (FILE * stream, + const gsl_vector_complex * v); +int gsl_vector_complex_fscanf (FILE * stream, + gsl_vector_complex * v); +int gsl_vector_complex_fprintf (FILE * stream, + const gsl_vector_complex * v, + const char *format); + +int gsl_vector_complex_memcpy (gsl_vector_complex * dest, const gsl_vector_complex * src); + +int gsl_vector_complex_reverse (gsl_vector_complex * v); + +int gsl_vector_complex_swap (gsl_vector_complex * v, gsl_vector_complex * w); +int gsl_vector_complex_swap_elements (gsl_vector_complex * v, const size_t i, const size_t j); + +int gsl_vector_complex_equal (const gsl_vector_complex * u, + const gsl_vector_complex * v); + +int gsl_vector_complex_isnull (const gsl_vector_complex * v); +int gsl_vector_complex_ispos (const gsl_vector_complex * v); +int gsl_vector_complex_isneg (const gsl_vector_complex * v); +int gsl_vector_complex_isnonneg (const gsl_vector_complex * v); + +int gsl_vector_complex_add (gsl_vector_complex * a, const gsl_vector_complex * b); +int gsl_vector_complex_sub (gsl_vector_complex * a, const gsl_vector_complex * b); +int gsl_vector_complex_mul (gsl_vector_complex * a, const gsl_vector_complex * b); +int gsl_vector_complex_div (gsl_vector_complex * a, const gsl_vector_complex * b); +int gsl_vector_complex_scale (gsl_vector_complex * a, const gsl_complex x); +int gsl_vector_complex_add_constant (gsl_vector_complex * a, const gsl_complex x); +int gsl_vector_complex_axpby (const gsl_complex alpha, const gsl_vector_complex * x, const gsl_complex beta, gsl_vector_complex * y); + +INLINE_DECL gsl_complex gsl_vector_complex_get (const gsl_vector_complex * v, const size_t i); +INLINE_DECL void gsl_vector_complex_set (gsl_vector_complex * v, const size_t i, gsl_complex z); +INLINE_DECL gsl_complex *gsl_vector_complex_ptr (gsl_vector_complex * v, const size_t i); +INLINE_DECL const gsl_complex *gsl_vector_complex_const_ptr (const gsl_vector_complex * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex +gsl_vector_complex_get (const gsl_vector_complex * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + gsl_complex zero = {{0, 0}}; + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); + } +#endif + return *GSL_COMPLEX_AT (v, i); +} + +INLINE_FUN +void +gsl_vector_complex_set (gsl_vector_complex * v, + const size_t i, gsl_complex z) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + *GSL_COMPLEX_AT (v, i) = z; +} + +INLINE_FUN +gsl_complex * +gsl_vector_complex_ptr (gsl_vector_complex * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_AT (v, i); +} + +INLINE_FUN +const gsl_complex * +gsl_vector_complex_const_ptr (const gsl_vector_complex * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_AT (v, i); +} + + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_COMPLEX_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_float.h new file mode 100644 index 0000000..d5721b7 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_float.h @@ -0,0 +1,252 @@ +/* vector/gsl_vector_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_COMPLEX_FLOAT_H__ +#define __GSL_VECTOR_COMPLEX_FLOAT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + float *data; + gsl_block_complex_float *block; + int owner; +} gsl_vector_complex_float; + +typedef struct +{ + gsl_vector_complex_float vector; +} _gsl_vector_complex_float_view; + +typedef _gsl_vector_complex_float_view gsl_vector_complex_float_view; + +typedef struct +{ + gsl_vector_complex_float vector; +} _gsl_vector_complex_float_const_view; + +typedef const _gsl_vector_complex_float_const_view gsl_vector_complex_float_const_view; + +/* Allocation */ + +gsl_vector_complex_float *gsl_vector_complex_float_alloc (const size_t n); +gsl_vector_complex_float *gsl_vector_complex_float_calloc (const size_t n); + +gsl_vector_complex_float * +gsl_vector_complex_float_alloc_from_block (gsl_block_complex_float * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_complex_float * +gsl_vector_complex_float_alloc_from_vector (gsl_vector_complex_float * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_complex_float_free (gsl_vector_complex_float * v); + +/* Views */ + +_gsl_vector_complex_float_view +gsl_vector_complex_float_view_array (float *base, + size_t n); + +_gsl_vector_complex_float_view +gsl_vector_complex_float_view_array_with_stride (float *base, + size_t stride, + size_t n); + +_gsl_vector_complex_float_const_view +gsl_vector_complex_float_const_view_array (const float *base, + size_t n); + +_gsl_vector_complex_float_const_view +gsl_vector_complex_float_const_view_array_with_stride (const float *base, + size_t stride, + size_t n); + +_gsl_vector_complex_float_view +gsl_vector_complex_float_subvector (gsl_vector_complex_float *base, + size_t i, + size_t n); + + +_gsl_vector_complex_float_view +gsl_vector_complex_float_subvector_with_stride (gsl_vector_complex_float *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_complex_float_const_view +gsl_vector_complex_float_const_subvector (const gsl_vector_complex_float *base, + size_t i, + size_t n); + + +_gsl_vector_complex_float_const_view +gsl_vector_complex_float_const_subvector_with_stride (const gsl_vector_complex_float *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_float_view +gsl_vector_complex_float_real (gsl_vector_complex_float *v); + +_gsl_vector_float_view +gsl_vector_complex_float_imag (gsl_vector_complex_float *v); + +_gsl_vector_float_const_view +gsl_vector_complex_float_const_real (const gsl_vector_complex_float *v); + +_gsl_vector_float_const_view +gsl_vector_complex_float_const_imag (const gsl_vector_complex_float *v); + + +/* Operations */ + +void gsl_vector_complex_float_set_zero (gsl_vector_complex_float * v); +void gsl_vector_complex_float_set_all (gsl_vector_complex_float * v, + gsl_complex_float z); +int gsl_vector_complex_float_set_basis (gsl_vector_complex_float * v, size_t i); + +int gsl_vector_complex_float_fread (FILE * stream, + gsl_vector_complex_float * v); +int gsl_vector_complex_float_fwrite (FILE * stream, + const gsl_vector_complex_float * v); +int gsl_vector_complex_float_fscanf (FILE * stream, + gsl_vector_complex_float * v); +int gsl_vector_complex_float_fprintf (FILE * stream, + const gsl_vector_complex_float * v, + const char *format); + +int gsl_vector_complex_float_memcpy (gsl_vector_complex_float * dest, const gsl_vector_complex_float * src); + +int gsl_vector_complex_float_reverse (gsl_vector_complex_float * v); + +int gsl_vector_complex_float_swap (gsl_vector_complex_float * v, gsl_vector_complex_float * w); +int gsl_vector_complex_float_swap_elements (gsl_vector_complex_float * v, const size_t i, const size_t j); + +int gsl_vector_complex_float_equal (const gsl_vector_complex_float * u, + const gsl_vector_complex_float * v); + +int gsl_vector_complex_float_isnull (const gsl_vector_complex_float * v); +int gsl_vector_complex_float_ispos (const gsl_vector_complex_float * v); +int gsl_vector_complex_float_isneg (const gsl_vector_complex_float * v); +int gsl_vector_complex_float_isnonneg (const gsl_vector_complex_float * v); + +int gsl_vector_complex_float_add (gsl_vector_complex_float * a, const gsl_vector_complex_float * b); +int gsl_vector_complex_float_sub (gsl_vector_complex_float * a, const gsl_vector_complex_float * b); +int gsl_vector_complex_float_mul (gsl_vector_complex_float * a, const gsl_vector_complex_float * b); +int gsl_vector_complex_float_div (gsl_vector_complex_float * a, const gsl_vector_complex_float * b); +int gsl_vector_complex_float_scale (gsl_vector_complex_float * a, const gsl_complex_float x); +int gsl_vector_complex_float_add_constant (gsl_vector_complex_float * a, const gsl_complex_float x); +int gsl_vector_complex_float_axpby (const gsl_complex_float alpha, const gsl_vector_complex_float * x, const gsl_complex_float beta, gsl_vector_complex_float * y); + +INLINE_DECL gsl_complex_float gsl_vector_complex_float_get (const gsl_vector_complex_float * v, const size_t i); +INLINE_DECL void gsl_vector_complex_float_set (gsl_vector_complex_float * v, const size_t i, gsl_complex_float z); +INLINE_DECL gsl_complex_float *gsl_vector_complex_float_ptr (gsl_vector_complex_float * v, const size_t i); +INLINE_DECL const gsl_complex_float *gsl_vector_complex_float_const_ptr (const gsl_vector_complex_float * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex_float +gsl_vector_complex_float_get (const gsl_vector_complex_float * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + gsl_complex_float zero = {{0, 0}}; + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); + } +#endif + return *GSL_COMPLEX_FLOAT_AT (v, i); +} + +INLINE_FUN +void +gsl_vector_complex_float_set (gsl_vector_complex_float * v, + const size_t i, gsl_complex_float z) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + *GSL_COMPLEX_FLOAT_AT (v, i) = z; +} + +INLINE_FUN +gsl_complex_float * +gsl_vector_complex_float_ptr (gsl_vector_complex_float * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_FLOAT_AT (v, i); +} + +INLINE_FUN +const gsl_complex_float * +gsl_vector_complex_float_const_ptr (const gsl_vector_complex_float * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_FLOAT_AT (v, i); +} + + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_COMPLEX_FLOAT_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_long_double.h new file mode 100644 index 0000000..b775ae2 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_complex_long_double.h @@ -0,0 +1,252 @@ +/* vector/gsl_vector_complex_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ +#define __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + long double *data; + gsl_block_complex_long_double *block; + int owner; +} gsl_vector_complex_long_double; + +typedef struct +{ + gsl_vector_complex_long_double vector; +} _gsl_vector_complex_long_double_view; + +typedef _gsl_vector_complex_long_double_view gsl_vector_complex_long_double_view; + +typedef struct +{ + gsl_vector_complex_long_double vector; +} _gsl_vector_complex_long_double_const_view; + +typedef const _gsl_vector_complex_long_double_const_view gsl_vector_complex_long_double_const_view; + +/* Allocation */ + +gsl_vector_complex_long_double *gsl_vector_complex_long_double_alloc (const size_t n); +gsl_vector_complex_long_double *gsl_vector_complex_long_double_calloc (const size_t n); + +gsl_vector_complex_long_double * +gsl_vector_complex_long_double_alloc_from_block (gsl_block_complex_long_double * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_complex_long_double * +gsl_vector_complex_long_double_alloc_from_vector (gsl_vector_complex_long_double * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_complex_long_double_free (gsl_vector_complex_long_double * v); + +/* Views */ + +_gsl_vector_complex_long_double_view +gsl_vector_complex_long_double_view_array (long double *base, + size_t n); + +_gsl_vector_complex_long_double_view +gsl_vector_complex_long_double_view_array_with_stride (long double *base, + size_t stride, + size_t n); + +_gsl_vector_complex_long_double_const_view +gsl_vector_complex_long_double_const_view_array (const long double *base, + size_t n); + +_gsl_vector_complex_long_double_const_view +gsl_vector_complex_long_double_const_view_array_with_stride (const long double *base, + size_t stride, + size_t n); + +_gsl_vector_complex_long_double_view +gsl_vector_complex_long_double_subvector (gsl_vector_complex_long_double *base, + size_t i, + size_t n); + + +_gsl_vector_complex_long_double_view +gsl_vector_complex_long_double_subvector_with_stride (gsl_vector_complex_long_double *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_complex_long_double_const_view +gsl_vector_complex_long_double_const_subvector (const gsl_vector_complex_long_double *base, + size_t i, + size_t n); + + +_gsl_vector_complex_long_double_const_view +gsl_vector_complex_long_double_const_subvector_with_stride (const gsl_vector_complex_long_double *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_long_double_view +gsl_vector_complex_long_double_real (gsl_vector_complex_long_double *v); + +_gsl_vector_long_double_view +gsl_vector_complex_long_double_imag (gsl_vector_complex_long_double *v); + +_gsl_vector_long_double_const_view +gsl_vector_complex_long_double_const_real (const gsl_vector_complex_long_double *v); + +_gsl_vector_long_double_const_view +gsl_vector_complex_long_double_const_imag (const gsl_vector_complex_long_double *v); + + +/* Operations */ + +void gsl_vector_complex_long_double_set_zero (gsl_vector_complex_long_double * v); +void gsl_vector_complex_long_double_set_all (gsl_vector_complex_long_double * v, + gsl_complex_long_double z); +int gsl_vector_complex_long_double_set_basis (gsl_vector_complex_long_double * v, size_t i); + +int gsl_vector_complex_long_double_fread (FILE * stream, + gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_fwrite (FILE * stream, + const gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_fscanf (FILE * stream, + gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_fprintf (FILE * stream, + const gsl_vector_complex_long_double * v, + const char *format); + +int gsl_vector_complex_long_double_memcpy (gsl_vector_complex_long_double * dest, const gsl_vector_complex_long_double * src); + +int gsl_vector_complex_long_double_reverse (gsl_vector_complex_long_double * v); + +int gsl_vector_complex_long_double_swap (gsl_vector_complex_long_double * v, gsl_vector_complex_long_double * w); +int gsl_vector_complex_long_double_swap_elements (gsl_vector_complex_long_double * v, const size_t i, const size_t j); + +int gsl_vector_complex_long_double_equal (const gsl_vector_complex_long_double * u, + const gsl_vector_complex_long_double * v); + +int gsl_vector_complex_long_double_isnull (const gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_ispos (const gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_isneg (const gsl_vector_complex_long_double * v); +int gsl_vector_complex_long_double_isnonneg (const gsl_vector_complex_long_double * v); + +int gsl_vector_complex_long_double_add (gsl_vector_complex_long_double * a, const gsl_vector_complex_long_double * b); +int gsl_vector_complex_long_double_sub (gsl_vector_complex_long_double * a, const gsl_vector_complex_long_double * b); +int gsl_vector_complex_long_double_mul (gsl_vector_complex_long_double * a, const gsl_vector_complex_long_double * b); +int gsl_vector_complex_long_double_div (gsl_vector_complex_long_double * a, const gsl_vector_complex_long_double * b); +int gsl_vector_complex_long_double_scale (gsl_vector_complex_long_double * a, const gsl_complex_long_double x); +int gsl_vector_complex_long_double_add_constant (gsl_vector_complex_long_double * a, const gsl_complex_long_double x); +int gsl_vector_complex_long_double_axpby (const gsl_complex_long_double alpha, const gsl_vector_complex_long_double * x, const gsl_complex_long_double beta, gsl_vector_complex_long_double * y); + +INLINE_DECL gsl_complex_long_double gsl_vector_complex_long_double_get (const gsl_vector_complex_long_double * v, const size_t i); +INLINE_DECL void gsl_vector_complex_long_double_set (gsl_vector_complex_long_double * v, const size_t i, gsl_complex_long_double z); +INLINE_DECL gsl_complex_long_double *gsl_vector_complex_long_double_ptr (gsl_vector_complex_long_double * v, const size_t i); +INLINE_DECL const gsl_complex_long_double *gsl_vector_complex_long_double_const_ptr (const gsl_vector_complex_long_double * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +gsl_complex_long_double +gsl_vector_complex_long_double_get (const gsl_vector_complex_long_double * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + gsl_complex_long_double zero = {{0, 0}}; + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, zero); + } +#endif + return *GSL_COMPLEX_LONG_DOUBLE_AT (v, i); +} + +INLINE_FUN +void +gsl_vector_complex_long_double_set (gsl_vector_complex_long_double * v, + const size_t i, gsl_complex_long_double z) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + *GSL_COMPLEX_LONG_DOUBLE_AT (v, i) = z; +} + +INLINE_FUN +gsl_complex_long_double * +gsl_vector_complex_long_double_ptr (gsl_vector_complex_long_double * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_LONG_DOUBLE_AT (v, i); +} + +INLINE_FUN +const gsl_complex_long_double * +gsl_vector_complex_long_double_const_ptr (const gsl_vector_complex_long_double * v, + const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return GSL_COMPLEX_LONG_DOUBLE_AT (v, i); +} + + +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_COMPLEX_LONG_DOUBLE_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_double.h new file mode 100644 index 0000000..02817e5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_double.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_DOUBLE_H__ +#define __GSL_VECTOR_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + double *data; + gsl_block *block; + int owner; +} +gsl_vector; + +typedef struct +{ + gsl_vector vector; +} _gsl_vector_view; + +typedef _gsl_vector_view gsl_vector_view; + +typedef struct +{ + gsl_vector vector; +} _gsl_vector_const_view; + +typedef const _gsl_vector_const_view gsl_vector_const_view; + + +/* Allocation */ + +gsl_vector *gsl_vector_alloc (const size_t n); +gsl_vector *gsl_vector_calloc (const size_t n); + +gsl_vector *gsl_vector_alloc_from_block (gsl_block * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector *gsl_vector_alloc_from_vector (gsl_vector * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_free (gsl_vector * v); + +/* Views */ + +_gsl_vector_view +gsl_vector_view_array (double *v, size_t n); + +_gsl_vector_view +gsl_vector_view_array_with_stride (double *base, + size_t stride, + size_t n); + +_gsl_vector_const_view +gsl_vector_const_view_array (const double *v, size_t n); + +_gsl_vector_const_view +gsl_vector_const_view_array_with_stride (const double *base, + size_t stride, + size_t n); + +_gsl_vector_view +gsl_vector_subvector (gsl_vector *v, + size_t i, + size_t n); + +_gsl_vector_view +gsl_vector_subvector_with_stride (gsl_vector *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_const_view +gsl_vector_const_subvector (const gsl_vector *v, + size_t i, + size_t n); + +_gsl_vector_const_view +gsl_vector_const_subvector_with_stride (const gsl_vector *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_set_zero (gsl_vector * v); +void gsl_vector_set_all (gsl_vector * v, double x); +int gsl_vector_set_basis (gsl_vector * v, size_t i); + +int gsl_vector_fread (FILE * stream, gsl_vector * v); +int gsl_vector_fwrite (FILE * stream, const gsl_vector * v); +int gsl_vector_fscanf (FILE * stream, gsl_vector * v); +int gsl_vector_fprintf (FILE * stream, const gsl_vector * v, + const char *format); + +int gsl_vector_memcpy (gsl_vector * dest, const gsl_vector * src); + +int gsl_vector_reverse (gsl_vector * v); + +int gsl_vector_swap (gsl_vector * v, gsl_vector * w); +int gsl_vector_swap_elements (gsl_vector * v, const size_t i, const size_t j); + +double gsl_vector_max (const gsl_vector * v); +double gsl_vector_min (const gsl_vector * v); +void gsl_vector_minmax (const gsl_vector * v, double * min_out, double * max_out); + +size_t gsl_vector_max_index (const gsl_vector * v); +size_t gsl_vector_min_index (const gsl_vector * v); +void gsl_vector_minmax_index (const gsl_vector * v, size_t * imin, size_t * imax); + +int gsl_vector_add (gsl_vector * a, const gsl_vector * b); +int gsl_vector_sub (gsl_vector * a, const gsl_vector * b); +int gsl_vector_mul (gsl_vector * a, const gsl_vector * b); +int gsl_vector_div (gsl_vector * a, const gsl_vector * b); +int gsl_vector_scale (gsl_vector * a, const double x); +int gsl_vector_add_constant (gsl_vector * a, const double x); +int gsl_vector_axpby (const double alpha, const gsl_vector * x, const double beta, gsl_vector * y); +double gsl_vector_sum (const gsl_vector * a); + +int gsl_vector_equal (const gsl_vector * u, + const gsl_vector * v); + +int gsl_vector_isnull (const gsl_vector * v); +int gsl_vector_ispos (const gsl_vector * v); +int gsl_vector_isneg (const gsl_vector * v); +int gsl_vector_isnonneg (const gsl_vector * v); + +INLINE_DECL double gsl_vector_get (const gsl_vector * v, const size_t i); +INLINE_DECL void gsl_vector_set (gsl_vector * v, const size_t i, double x); +INLINE_DECL double * gsl_vector_ptr (gsl_vector * v, const size_t i); +INLINE_DECL const double * gsl_vector_const_ptr (const gsl_vector * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +double +gsl_vector_get (const gsl_vector * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_set (gsl_vector * v, const size_t i, double x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +double * +gsl_vector_ptr (gsl_vector * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (double *) (v->data + i * v->stride); +} + +INLINE_FUN +const double * +gsl_vector_const_ptr (const gsl_vector * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const double *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_DOUBLE_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_float.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_float.h new file mode 100644 index 0000000..c4500f1 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_float.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_FLOAT_H__ +#define __GSL_VECTOR_FLOAT_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + float *data; + gsl_block_float *block; + int owner; +} +gsl_vector_float; + +typedef struct +{ + gsl_vector_float vector; +} _gsl_vector_float_view; + +typedef _gsl_vector_float_view gsl_vector_float_view; + +typedef struct +{ + gsl_vector_float vector; +} _gsl_vector_float_const_view; + +typedef const _gsl_vector_float_const_view gsl_vector_float_const_view; + + +/* Allocation */ + +gsl_vector_float *gsl_vector_float_alloc (const size_t n); +gsl_vector_float *gsl_vector_float_calloc (const size_t n); + +gsl_vector_float *gsl_vector_float_alloc_from_block (gsl_block_float * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_float *gsl_vector_float_alloc_from_vector (gsl_vector_float * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_float_free (gsl_vector_float * v); + +/* Views */ + +_gsl_vector_float_view +gsl_vector_float_view_array (float *v, size_t n); + +_gsl_vector_float_view +gsl_vector_float_view_array_with_stride (float *base, + size_t stride, + size_t n); + +_gsl_vector_float_const_view +gsl_vector_float_const_view_array (const float *v, size_t n); + +_gsl_vector_float_const_view +gsl_vector_float_const_view_array_with_stride (const float *base, + size_t stride, + size_t n); + +_gsl_vector_float_view +gsl_vector_float_subvector (gsl_vector_float *v, + size_t i, + size_t n); + +_gsl_vector_float_view +gsl_vector_float_subvector_with_stride (gsl_vector_float *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_float_const_view +gsl_vector_float_const_subvector (const gsl_vector_float *v, + size_t i, + size_t n); + +_gsl_vector_float_const_view +gsl_vector_float_const_subvector_with_stride (const gsl_vector_float *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_float_set_zero (gsl_vector_float * v); +void gsl_vector_float_set_all (gsl_vector_float * v, float x); +int gsl_vector_float_set_basis (gsl_vector_float * v, size_t i); + +int gsl_vector_float_fread (FILE * stream, gsl_vector_float * v); +int gsl_vector_float_fwrite (FILE * stream, const gsl_vector_float * v); +int gsl_vector_float_fscanf (FILE * stream, gsl_vector_float * v); +int gsl_vector_float_fprintf (FILE * stream, const gsl_vector_float * v, + const char *format); + +int gsl_vector_float_memcpy (gsl_vector_float * dest, const gsl_vector_float * src); + +int gsl_vector_float_reverse (gsl_vector_float * v); + +int gsl_vector_float_swap (gsl_vector_float * v, gsl_vector_float * w); +int gsl_vector_float_swap_elements (gsl_vector_float * v, const size_t i, const size_t j); + +float gsl_vector_float_max (const gsl_vector_float * v); +float gsl_vector_float_min (const gsl_vector_float * v); +void gsl_vector_float_minmax (const gsl_vector_float * v, float * min_out, float * max_out); + +size_t gsl_vector_float_max_index (const gsl_vector_float * v); +size_t gsl_vector_float_min_index (const gsl_vector_float * v); +void gsl_vector_float_minmax_index (const gsl_vector_float * v, size_t * imin, size_t * imax); + +int gsl_vector_float_add (gsl_vector_float * a, const gsl_vector_float * b); +int gsl_vector_float_sub (gsl_vector_float * a, const gsl_vector_float * b); +int gsl_vector_float_mul (gsl_vector_float * a, const gsl_vector_float * b); +int gsl_vector_float_div (gsl_vector_float * a, const gsl_vector_float * b); +int gsl_vector_float_scale (gsl_vector_float * a, const float x); +int gsl_vector_float_add_constant (gsl_vector_float * a, const float x); +int gsl_vector_float_axpby (const float alpha, const gsl_vector_float * x, const float beta, gsl_vector_float * y); +float gsl_vector_float_sum (const gsl_vector_float * a); + +int gsl_vector_float_equal (const gsl_vector_float * u, + const gsl_vector_float * v); + +int gsl_vector_float_isnull (const gsl_vector_float * v); +int gsl_vector_float_ispos (const gsl_vector_float * v); +int gsl_vector_float_isneg (const gsl_vector_float * v); +int gsl_vector_float_isnonneg (const gsl_vector_float * v); + +INLINE_DECL float gsl_vector_float_get (const gsl_vector_float * v, const size_t i); +INLINE_DECL void gsl_vector_float_set (gsl_vector_float * v, const size_t i, float x); +INLINE_DECL float * gsl_vector_float_ptr (gsl_vector_float * v, const size_t i); +INLINE_DECL const float * gsl_vector_float_const_ptr (const gsl_vector_float * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +float +gsl_vector_float_get (const gsl_vector_float * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_float_set (gsl_vector_float * v, const size_t i, float x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +float * +gsl_vector_float_ptr (gsl_vector_float * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (float *) (v->data + i * v->stride); +} + +INLINE_FUN +const float * +gsl_vector_float_const_ptr (const gsl_vector_float * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const float *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_FLOAT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_int.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_int.h new file mode 100644 index 0000000..9f61c48 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_int.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_int.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_INT_H__ +#define __GSL_VECTOR_INT_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + int *data; + gsl_block_int *block; + int owner; +} +gsl_vector_int; + +typedef struct +{ + gsl_vector_int vector; +} _gsl_vector_int_view; + +typedef _gsl_vector_int_view gsl_vector_int_view; + +typedef struct +{ + gsl_vector_int vector; +} _gsl_vector_int_const_view; + +typedef const _gsl_vector_int_const_view gsl_vector_int_const_view; + + +/* Allocation */ + +gsl_vector_int *gsl_vector_int_alloc (const size_t n); +gsl_vector_int *gsl_vector_int_calloc (const size_t n); + +gsl_vector_int *gsl_vector_int_alloc_from_block (gsl_block_int * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_int *gsl_vector_int_alloc_from_vector (gsl_vector_int * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_int_free (gsl_vector_int * v); + +/* Views */ + +_gsl_vector_int_view +gsl_vector_int_view_array (int *v, size_t n); + +_gsl_vector_int_view +gsl_vector_int_view_array_with_stride (int *base, + size_t stride, + size_t n); + +_gsl_vector_int_const_view +gsl_vector_int_const_view_array (const int *v, size_t n); + +_gsl_vector_int_const_view +gsl_vector_int_const_view_array_with_stride (const int *base, + size_t stride, + size_t n); + +_gsl_vector_int_view +gsl_vector_int_subvector (gsl_vector_int *v, + size_t i, + size_t n); + +_gsl_vector_int_view +gsl_vector_int_subvector_with_stride (gsl_vector_int *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_int_const_view +gsl_vector_int_const_subvector (const gsl_vector_int *v, + size_t i, + size_t n); + +_gsl_vector_int_const_view +gsl_vector_int_const_subvector_with_stride (const gsl_vector_int *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_int_set_zero (gsl_vector_int * v); +void gsl_vector_int_set_all (gsl_vector_int * v, int x); +int gsl_vector_int_set_basis (gsl_vector_int * v, size_t i); + +int gsl_vector_int_fread (FILE * stream, gsl_vector_int * v); +int gsl_vector_int_fwrite (FILE * stream, const gsl_vector_int * v); +int gsl_vector_int_fscanf (FILE * stream, gsl_vector_int * v); +int gsl_vector_int_fprintf (FILE * stream, const gsl_vector_int * v, + const char *format); + +int gsl_vector_int_memcpy (gsl_vector_int * dest, const gsl_vector_int * src); + +int gsl_vector_int_reverse (gsl_vector_int * v); + +int gsl_vector_int_swap (gsl_vector_int * v, gsl_vector_int * w); +int gsl_vector_int_swap_elements (gsl_vector_int * v, const size_t i, const size_t j); + +int gsl_vector_int_max (const gsl_vector_int * v); +int gsl_vector_int_min (const gsl_vector_int * v); +void gsl_vector_int_minmax (const gsl_vector_int * v, int * min_out, int * max_out); + +size_t gsl_vector_int_max_index (const gsl_vector_int * v); +size_t gsl_vector_int_min_index (const gsl_vector_int * v); +void gsl_vector_int_minmax_index (const gsl_vector_int * v, size_t * imin, size_t * imax); + +int gsl_vector_int_add (gsl_vector_int * a, const gsl_vector_int * b); +int gsl_vector_int_sub (gsl_vector_int * a, const gsl_vector_int * b); +int gsl_vector_int_mul (gsl_vector_int * a, const gsl_vector_int * b); +int gsl_vector_int_div (gsl_vector_int * a, const gsl_vector_int * b); +int gsl_vector_int_scale (gsl_vector_int * a, const int x); +int gsl_vector_int_add_constant (gsl_vector_int * a, const int x); +int gsl_vector_int_axpby (const int alpha, const gsl_vector_int * x, const int beta, gsl_vector_int * y); +int gsl_vector_int_sum (const gsl_vector_int * a); + +int gsl_vector_int_equal (const gsl_vector_int * u, + const gsl_vector_int * v); + +int gsl_vector_int_isnull (const gsl_vector_int * v); +int gsl_vector_int_ispos (const gsl_vector_int * v); +int gsl_vector_int_isneg (const gsl_vector_int * v); +int gsl_vector_int_isnonneg (const gsl_vector_int * v); + +INLINE_DECL int gsl_vector_int_get (const gsl_vector_int * v, const size_t i); +INLINE_DECL void gsl_vector_int_set (gsl_vector_int * v, const size_t i, int x); +INLINE_DECL int * gsl_vector_int_ptr (gsl_vector_int * v, const size_t i); +INLINE_DECL const int * gsl_vector_int_const_ptr (const gsl_vector_int * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +int +gsl_vector_int_get (const gsl_vector_int * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_int_set (gsl_vector_int * v, const size_t i, int x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +int * +gsl_vector_int_ptr (gsl_vector_int * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (int *) (v->data + i * v->stride); +} + +INLINE_FUN +const int * +gsl_vector_int_const_ptr (const gsl_vector_int * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const int *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_INT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long.h new file mode 100644 index 0000000..5b7e4bd --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_long.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_LONG_H__ +#define __GSL_VECTOR_LONG_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + long *data; + gsl_block_long *block; + int owner; +} +gsl_vector_long; + +typedef struct +{ + gsl_vector_long vector; +} _gsl_vector_long_view; + +typedef _gsl_vector_long_view gsl_vector_long_view; + +typedef struct +{ + gsl_vector_long vector; +} _gsl_vector_long_const_view; + +typedef const _gsl_vector_long_const_view gsl_vector_long_const_view; + + +/* Allocation */ + +gsl_vector_long *gsl_vector_long_alloc (const size_t n); +gsl_vector_long *gsl_vector_long_calloc (const size_t n); + +gsl_vector_long *gsl_vector_long_alloc_from_block (gsl_block_long * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_long *gsl_vector_long_alloc_from_vector (gsl_vector_long * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_long_free (gsl_vector_long * v); + +/* Views */ + +_gsl_vector_long_view +gsl_vector_long_view_array (long *v, size_t n); + +_gsl_vector_long_view +gsl_vector_long_view_array_with_stride (long *base, + size_t stride, + size_t n); + +_gsl_vector_long_const_view +gsl_vector_long_const_view_array (const long *v, size_t n); + +_gsl_vector_long_const_view +gsl_vector_long_const_view_array_with_stride (const long *base, + size_t stride, + size_t n); + +_gsl_vector_long_view +gsl_vector_long_subvector (gsl_vector_long *v, + size_t i, + size_t n); + +_gsl_vector_long_view +gsl_vector_long_subvector_with_stride (gsl_vector_long *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_long_const_view +gsl_vector_long_const_subvector (const gsl_vector_long *v, + size_t i, + size_t n); + +_gsl_vector_long_const_view +gsl_vector_long_const_subvector_with_stride (const gsl_vector_long *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_long_set_zero (gsl_vector_long * v); +void gsl_vector_long_set_all (gsl_vector_long * v, long x); +int gsl_vector_long_set_basis (gsl_vector_long * v, size_t i); + +int gsl_vector_long_fread (FILE * stream, gsl_vector_long * v); +int gsl_vector_long_fwrite (FILE * stream, const gsl_vector_long * v); +int gsl_vector_long_fscanf (FILE * stream, gsl_vector_long * v); +int gsl_vector_long_fprintf (FILE * stream, const gsl_vector_long * v, + const char *format); + +int gsl_vector_long_memcpy (gsl_vector_long * dest, const gsl_vector_long * src); + +int gsl_vector_long_reverse (gsl_vector_long * v); + +int gsl_vector_long_swap (gsl_vector_long * v, gsl_vector_long * w); +int gsl_vector_long_swap_elements (gsl_vector_long * v, const size_t i, const size_t j); + +long gsl_vector_long_max (const gsl_vector_long * v); +long gsl_vector_long_min (const gsl_vector_long * v); +void gsl_vector_long_minmax (const gsl_vector_long * v, long * min_out, long * max_out); + +size_t gsl_vector_long_max_index (const gsl_vector_long * v); +size_t gsl_vector_long_min_index (const gsl_vector_long * v); +void gsl_vector_long_minmax_index (const gsl_vector_long * v, size_t * imin, size_t * imax); + +int gsl_vector_long_add (gsl_vector_long * a, const gsl_vector_long * b); +int gsl_vector_long_sub (gsl_vector_long * a, const gsl_vector_long * b); +int gsl_vector_long_mul (gsl_vector_long * a, const gsl_vector_long * b); +int gsl_vector_long_div (gsl_vector_long * a, const gsl_vector_long * b); +int gsl_vector_long_scale (gsl_vector_long * a, const long x); +int gsl_vector_long_add_constant (gsl_vector_long * a, const long x); +int gsl_vector_long_axpby (const long alpha, const gsl_vector_long * x, const long beta, gsl_vector_long * y); +long gsl_vector_long_sum (const gsl_vector_long * a); + +int gsl_vector_long_equal (const gsl_vector_long * u, + const gsl_vector_long * v); + +int gsl_vector_long_isnull (const gsl_vector_long * v); +int gsl_vector_long_ispos (const gsl_vector_long * v); +int gsl_vector_long_isneg (const gsl_vector_long * v); +int gsl_vector_long_isnonneg (const gsl_vector_long * v); + +INLINE_DECL long gsl_vector_long_get (const gsl_vector_long * v, const size_t i); +INLINE_DECL void gsl_vector_long_set (gsl_vector_long * v, const size_t i, long x); +INLINE_DECL long * gsl_vector_long_ptr (gsl_vector_long * v, const size_t i); +INLINE_DECL const long * gsl_vector_long_const_ptr (const gsl_vector_long * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +long +gsl_vector_long_get (const gsl_vector_long * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_long_set (gsl_vector_long * v, const size_t i, long x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +long * +gsl_vector_long_ptr (gsl_vector_long * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (long *) (v->data + i * v->stride); +} + +INLINE_FUN +const long * +gsl_vector_long_const_ptr (const gsl_vector_long * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const long *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_LONG_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long_double.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long_double.h new file mode 100644 index 0000000..369fcd5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_long_double.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_long_double.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_LONG_DOUBLE_H__ +#define __GSL_VECTOR_LONG_DOUBLE_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + long double *data; + gsl_block_long_double *block; + int owner; +} +gsl_vector_long_double; + +typedef struct +{ + gsl_vector_long_double vector; +} _gsl_vector_long_double_view; + +typedef _gsl_vector_long_double_view gsl_vector_long_double_view; + +typedef struct +{ + gsl_vector_long_double vector; +} _gsl_vector_long_double_const_view; + +typedef const _gsl_vector_long_double_const_view gsl_vector_long_double_const_view; + + +/* Allocation */ + +gsl_vector_long_double *gsl_vector_long_double_alloc (const size_t n); +gsl_vector_long_double *gsl_vector_long_double_calloc (const size_t n); + +gsl_vector_long_double *gsl_vector_long_double_alloc_from_block (gsl_block_long_double * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_long_double *gsl_vector_long_double_alloc_from_vector (gsl_vector_long_double * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_long_double_free (gsl_vector_long_double * v); + +/* Views */ + +_gsl_vector_long_double_view +gsl_vector_long_double_view_array (long double *v, size_t n); + +_gsl_vector_long_double_view +gsl_vector_long_double_view_array_with_stride (long double *base, + size_t stride, + size_t n); + +_gsl_vector_long_double_const_view +gsl_vector_long_double_const_view_array (const long double *v, size_t n); + +_gsl_vector_long_double_const_view +gsl_vector_long_double_const_view_array_with_stride (const long double *base, + size_t stride, + size_t n); + +_gsl_vector_long_double_view +gsl_vector_long_double_subvector (gsl_vector_long_double *v, + size_t i, + size_t n); + +_gsl_vector_long_double_view +gsl_vector_long_double_subvector_with_stride (gsl_vector_long_double *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_long_double_const_view +gsl_vector_long_double_const_subvector (const gsl_vector_long_double *v, + size_t i, + size_t n); + +_gsl_vector_long_double_const_view +gsl_vector_long_double_const_subvector_with_stride (const gsl_vector_long_double *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_long_double_set_zero (gsl_vector_long_double * v); +void gsl_vector_long_double_set_all (gsl_vector_long_double * v, long double x); +int gsl_vector_long_double_set_basis (gsl_vector_long_double * v, size_t i); + +int gsl_vector_long_double_fread (FILE * stream, gsl_vector_long_double * v); +int gsl_vector_long_double_fwrite (FILE * stream, const gsl_vector_long_double * v); +int gsl_vector_long_double_fscanf (FILE * stream, gsl_vector_long_double * v); +int gsl_vector_long_double_fprintf (FILE * stream, const gsl_vector_long_double * v, + const char *format); + +int gsl_vector_long_double_memcpy (gsl_vector_long_double * dest, const gsl_vector_long_double * src); + +int gsl_vector_long_double_reverse (gsl_vector_long_double * v); + +int gsl_vector_long_double_swap (gsl_vector_long_double * v, gsl_vector_long_double * w); +int gsl_vector_long_double_swap_elements (gsl_vector_long_double * v, const size_t i, const size_t j); + +long double gsl_vector_long_double_max (const gsl_vector_long_double * v); +long double gsl_vector_long_double_min (const gsl_vector_long_double * v); +void gsl_vector_long_double_minmax (const gsl_vector_long_double * v, long double * min_out, long double * max_out); + +size_t gsl_vector_long_double_max_index (const gsl_vector_long_double * v); +size_t gsl_vector_long_double_min_index (const gsl_vector_long_double * v); +void gsl_vector_long_double_minmax_index (const gsl_vector_long_double * v, size_t * imin, size_t * imax); + +int gsl_vector_long_double_add (gsl_vector_long_double * a, const gsl_vector_long_double * b); +int gsl_vector_long_double_sub (gsl_vector_long_double * a, const gsl_vector_long_double * b); +int gsl_vector_long_double_mul (gsl_vector_long_double * a, const gsl_vector_long_double * b); +int gsl_vector_long_double_div (gsl_vector_long_double * a, const gsl_vector_long_double * b); +int gsl_vector_long_double_scale (gsl_vector_long_double * a, const long double x); +int gsl_vector_long_double_add_constant (gsl_vector_long_double * a, const long double x); +int gsl_vector_long_double_axpby (const long double alpha, const gsl_vector_long_double * x, const long double beta, gsl_vector_long_double * y); +long double gsl_vector_long_double_sum (const gsl_vector_long_double * a); + +int gsl_vector_long_double_equal (const gsl_vector_long_double * u, + const gsl_vector_long_double * v); + +int gsl_vector_long_double_isnull (const gsl_vector_long_double * v); +int gsl_vector_long_double_ispos (const gsl_vector_long_double * v); +int gsl_vector_long_double_isneg (const gsl_vector_long_double * v); +int gsl_vector_long_double_isnonneg (const gsl_vector_long_double * v); + +INLINE_DECL long double gsl_vector_long_double_get (const gsl_vector_long_double * v, const size_t i); +INLINE_DECL void gsl_vector_long_double_set (gsl_vector_long_double * v, const size_t i, long double x); +INLINE_DECL long double * gsl_vector_long_double_ptr (gsl_vector_long_double * v, const size_t i); +INLINE_DECL const long double * gsl_vector_long_double_const_ptr (const gsl_vector_long_double * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +long double +gsl_vector_long_double_get (const gsl_vector_long_double * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_long_double_set (gsl_vector_long_double * v, const size_t i, long double x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +long double * +gsl_vector_long_double_ptr (gsl_vector_long_double * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (long double *) (v->data + i * v->stride); +} + +INLINE_FUN +const long double * +gsl_vector_long_double_const_ptr (const gsl_vector_long_double * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const long double *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_LONG_DOUBLE_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_short.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_short.h new file mode 100644 index 0000000..fedde18 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_short.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_short.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_SHORT_H__ +#define __GSL_VECTOR_SHORT_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + short *data; + gsl_block_short *block; + int owner; +} +gsl_vector_short; + +typedef struct +{ + gsl_vector_short vector; +} _gsl_vector_short_view; + +typedef _gsl_vector_short_view gsl_vector_short_view; + +typedef struct +{ + gsl_vector_short vector; +} _gsl_vector_short_const_view; + +typedef const _gsl_vector_short_const_view gsl_vector_short_const_view; + + +/* Allocation */ + +gsl_vector_short *gsl_vector_short_alloc (const size_t n); +gsl_vector_short *gsl_vector_short_calloc (const size_t n); + +gsl_vector_short *gsl_vector_short_alloc_from_block (gsl_block_short * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_short *gsl_vector_short_alloc_from_vector (gsl_vector_short * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_short_free (gsl_vector_short * v); + +/* Views */ + +_gsl_vector_short_view +gsl_vector_short_view_array (short *v, size_t n); + +_gsl_vector_short_view +gsl_vector_short_view_array_with_stride (short *base, + size_t stride, + size_t n); + +_gsl_vector_short_const_view +gsl_vector_short_const_view_array (const short *v, size_t n); + +_gsl_vector_short_const_view +gsl_vector_short_const_view_array_with_stride (const short *base, + size_t stride, + size_t n); + +_gsl_vector_short_view +gsl_vector_short_subvector (gsl_vector_short *v, + size_t i, + size_t n); + +_gsl_vector_short_view +gsl_vector_short_subvector_with_stride (gsl_vector_short *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_short_const_view +gsl_vector_short_const_subvector (const gsl_vector_short *v, + size_t i, + size_t n); + +_gsl_vector_short_const_view +gsl_vector_short_const_subvector_with_stride (const gsl_vector_short *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_short_set_zero (gsl_vector_short * v); +void gsl_vector_short_set_all (gsl_vector_short * v, short x); +int gsl_vector_short_set_basis (gsl_vector_short * v, size_t i); + +int gsl_vector_short_fread (FILE * stream, gsl_vector_short * v); +int gsl_vector_short_fwrite (FILE * stream, const gsl_vector_short * v); +int gsl_vector_short_fscanf (FILE * stream, gsl_vector_short * v); +int gsl_vector_short_fprintf (FILE * stream, const gsl_vector_short * v, + const char *format); + +int gsl_vector_short_memcpy (gsl_vector_short * dest, const gsl_vector_short * src); + +int gsl_vector_short_reverse (gsl_vector_short * v); + +int gsl_vector_short_swap (gsl_vector_short * v, gsl_vector_short * w); +int gsl_vector_short_swap_elements (gsl_vector_short * v, const size_t i, const size_t j); + +short gsl_vector_short_max (const gsl_vector_short * v); +short gsl_vector_short_min (const gsl_vector_short * v); +void gsl_vector_short_minmax (const gsl_vector_short * v, short * min_out, short * max_out); + +size_t gsl_vector_short_max_index (const gsl_vector_short * v); +size_t gsl_vector_short_min_index (const gsl_vector_short * v); +void gsl_vector_short_minmax_index (const gsl_vector_short * v, size_t * imin, size_t * imax); + +int gsl_vector_short_add (gsl_vector_short * a, const gsl_vector_short * b); +int gsl_vector_short_sub (gsl_vector_short * a, const gsl_vector_short * b); +int gsl_vector_short_mul (gsl_vector_short * a, const gsl_vector_short * b); +int gsl_vector_short_div (gsl_vector_short * a, const gsl_vector_short * b); +int gsl_vector_short_scale (gsl_vector_short * a, const short x); +int gsl_vector_short_add_constant (gsl_vector_short * a, const short x); +int gsl_vector_short_axpby (const short alpha, const gsl_vector_short * x, const short beta, gsl_vector_short * y); +short gsl_vector_short_sum (const gsl_vector_short * a); + +int gsl_vector_short_equal (const gsl_vector_short * u, + const gsl_vector_short * v); + +int gsl_vector_short_isnull (const gsl_vector_short * v); +int gsl_vector_short_ispos (const gsl_vector_short * v); +int gsl_vector_short_isneg (const gsl_vector_short * v); +int gsl_vector_short_isnonneg (const gsl_vector_short * v); + +INLINE_DECL short gsl_vector_short_get (const gsl_vector_short * v, const size_t i); +INLINE_DECL void gsl_vector_short_set (gsl_vector_short * v, const size_t i, short x); +INLINE_DECL short * gsl_vector_short_ptr (gsl_vector_short * v, const size_t i); +INLINE_DECL const short * gsl_vector_short_const_ptr (const gsl_vector_short * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +short +gsl_vector_short_get (const gsl_vector_short * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_short_set (gsl_vector_short * v, const size_t i, short x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +short * +gsl_vector_short_ptr (gsl_vector_short * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (short *) (v->data + i * v->stride); +} + +INLINE_FUN +const short * +gsl_vector_short_const_ptr (const gsl_vector_short * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const short *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_SHORT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uchar.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uchar.h new file mode 100644 index 0000000..2625c7c --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uchar.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_uchar.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_UCHAR_H__ +#define __GSL_VECTOR_UCHAR_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + unsigned char *data; + gsl_block_uchar *block; + int owner; +} +gsl_vector_uchar; + +typedef struct +{ + gsl_vector_uchar vector; +} _gsl_vector_uchar_view; + +typedef _gsl_vector_uchar_view gsl_vector_uchar_view; + +typedef struct +{ + gsl_vector_uchar vector; +} _gsl_vector_uchar_const_view; + +typedef const _gsl_vector_uchar_const_view gsl_vector_uchar_const_view; + + +/* Allocation */ + +gsl_vector_uchar *gsl_vector_uchar_alloc (const size_t n); +gsl_vector_uchar *gsl_vector_uchar_calloc (const size_t n); + +gsl_vector_uchar *gsl_vector_uchar_alloc_from_block (gsl_block_uchar * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_uchar *gsl_vector_uchar_alloc_from_vector (gsl_vector_uchar * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_uchar_free (gsl_vector_uchar * v); + +/* Views */ + +_gsl_vector_uchar_view +gsl_vector_uchar_view_array (unsigned char *v, size_t n); + +_gsl_vector_uchar_view +gsl_vector_uchar_view_array_with_stride (unsigned char *base, + size_t stride, + size_t n); + +_gsl_vector_uchar_const_view +gsl_vector_uchar_const_view_array (const unsigned char *v, size_t n); + +_gsl_vector_uchar_const_view +gsl_vector_uchar_const_view_array_with_stride (const unsigned char *base, + size_t stride, + size_t n); + +_gsl_vector_uchar_view +gsl_vector_uchar_subvector (gsl_vector_uchar *v, + size_t i, + size_t n); + +_gsl_vector_uchar_view +gsl_vector_uchar_subvector_with_stride (gsl_vector_uchar *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_uchar_const_view +gsl_vector_uchar_const_subvector (const gsl_vector_uchar *v, + size_t i, + size_t n); + +_gsl_vector_uchar_const_view +gsl_vector_uchar_const_subvector_with_stride (const gsl_vector_uchar *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_uchar_set_zero (gsl_vector_uchar * v); +void gsl_vector_uchar_set_all (gsl_vector_uchar * v, unsigned char x); +int gsl_vector_uchar_set_basis (gsl_vector_uchar * v, size_t i); + +int gsl_vector_uchar_fread (FILE * stream, gsl_vector_uchar * v); +int gsl_vector_uchar_fwrite (FILE * stream, const gsl_vector_uchar * v); +int gsl_vector_uchar_fscanf (FILE * stream, gsl_vector_uchar * v); +int gsl_vector_uchar_fprintf (FILE * stream, const gsl_vector_uchar * v, + const char *format); + +int gsl_vector_uchar_memcpy (gsl_vector_uchar * dest, const gsl_vector_uchar * src); + +int gsl_vector_uchar_reverse (gsl_vector_uchar * v); + +int gsl_vector_uchar_swap (gsl_vector_uchar * v, gsl_vector_uchar * w); +int gsl_vector_uchar_swap_elements (gsl_vector_uchar * v, const size_t i, const size_t j); + +unsigned char gsl_vector_uchar_max (const gsl_vector_uchar * v); +unsigned char gsl_vector_uchar_min (const gsl_vector_uchar * v); +void gsl_vector_uchar_minmax (const gsl_vector_uchar * v, unsigned char * min_out, unsigned char * max_out); + +size_t gsl_vector_uchar_max_index (const gsl_vector_uchar * v); +size_t gsl_vector_uchar_min_index (const gsl_vector_uchar * v); +void gsl_vector_uchar_minmax_index (const gsl_vector_uchar * v, size_t * imin, size_t * imax); + +int gsl_vector_uchar_add (gsl_vector_uchar * a, const gsl_vector_uchar * b); +int gsl_vector_uchar_sub (gsl_vector_uchar * a, const gsl_vector_uchar * b); +int gsl_vector_uchar_mul (gsl_vector_uchar * a, const gsl_vector_uchar * b); +int gsl_vector_uchar_div (gsl_vector_uchar * a, const gsl_vector_uchar * b); +int gsl_vector_uchar_scale (gsl_vector_uchar * a, const unsigned char x); +int gsl_vector_uchar_add_constant (gsl_vector_uchar * a, const unsigned char x); +int gsl_vector_uchar_axpby (const unsigned char alpha, const gsl_vector_uchar * x, const unsigned char beta, gsl_vector_uchar * y); +unsigned char gsl_vector_uchar_sum (const gsl_vector_uchar * a); + +int gsl_vector_uchar_equal (const gsl_vector_uchar * u, + const gsl_vector_uchar * v); + +int gsl_vector_uchar_isnull (const gsl_vector_uchar * v); +int gsl_vector_uchar_ispos (const gsl_vector_uchar * v); +int gsl_vector_uchar_isneg (const gsl_vector_uchar * v); +int gsl_vector_uchar_isnonneg (const gsl_vector_uchar * v); + +INLINE_DECL unsigned char gsl_vector_uchar_get (const gsl_vector_uchar * v, const size_t i); +INLINE_DECL void gsl_vector_uchar_set (gsl_vector_uchar * v, const size_t i, unsigned char x); +INLINE_DECL unsigned char * gsl_vector_uchar_ptr (gsl_vector_uchar * v, const size_t i); +INLINE_DECL const unsigned char * gsl_vector_uchar_const_ptr (const gsl_vector_uchar * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +unsigned char +gsl_vector_uchar_get (const gsl_vector_uchar * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_uchar_set (gsl_vector_uchar * v, const size_t i, unsigned char x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +unsigned char * +gsl_vector_uchar_ptr (gsl_vector_uchar * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (unsigned char *) (v->data + i * v->stride); +} + +INLINE_FUN +const unsigned char * +gsl_vector_uchar_const_ptr (const gsl_vector_uchar * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const unsigned char *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_UCHAR_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uint.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uint.h new file mode 100644 index 0000000..03cb7f5 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_uint.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_uint.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_UINT_H__ +#define __GSL_VECTOR_UINT_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + unsigned int *data; + gsl_block_uint *block; + int owner; +} +gsl_vector_uint; + +typedef struct +{ + gsl_vector_uint vector; +} _gsl_vector_uint_view; + +typedef _gsl_vector_uint_view gsl_vector_uint_view; + +typedef struct +{ + gsl_vector_uint vector; +} _gsl_vector_uint_const_view; + +typedef const _gsl_vector_uint_const_view gsl_vector_uint_const_view; + + +/* Allocation */ + +gsl_vector_uint *gsl_vector_uint_alloc (const size_t n); +gsl_vector_uint *gsl_vector_uint_calloc (const size_t n); + +gsl_vector_uint *gsl_vector_uint_alloc_from_block (gsl_block_uint * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_uint *gsl_vector_uint_alloc_from_vector (gsl_vector_uint * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_uint_free (gsl_vector_uint * v); + +/* Views */ + +_gsl_vector_uint_view +gsl_vector_uint_view_array (unsigned int *v, size_t n); + +_gsl_vector_uint_view +gsl_vector_uint_view_array_with_stride (unsigned int *base, + size_t stride, + size_t n); + +_gsl_vector_uint_const_view +gsl_vector_uint_const_view_array (const unsigned int *v, size_t n); + +_gsl_vector_uint_const_view +gsl_vector_uint_const_view_array_with_stride (const unsigned int *base, + size_t stride, + size_t n); + +_gsl_vector_uint_view +gsl_vector_uint_subvector (gsl_vector_uint *v, + size_t i, + size_t n); + +_gsl_vector_uint_view +gsl_vector_uint_subvector_with_stride (gsl_vector_uint *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_uint_const_view +gsl_vector_uint_const_subvector (const gsl_vector_uint *v, + size_t i, + size_t n); + +_gsl_vector_uint_const_view +gsl_vector_uint_const_subvector_with_stride (const gsl_vector_uint *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_uint_set_zero (gsl_vector_uint * v); +void gsl_vector_uint_set_all (gsl_vector_uint * v, unsigned int x); +int gsl_vector_uint_set_basis (gsl_vector_uint * v, size_t i); + +int gsl_vector_uint_fread (FILE * stream, gsl_vector_uint * v); +int gsl_vector_uint_fwrite (FILE * stream, const gsl_vector_uint * v); +int gsl_vector_uint_fscanf (FILE * stream, gsl_vector_uint * v); +int gsl_vector_uint_fprintf (FILE * stream, const gsl_vector_uint * v, + const char *format); + +int gsl_vector_uint_memcpy (gsl_vector_uint * dest, const gsl_vector_uint * src); + +int gsl_vector_uint_reverse (gsl_vector_uint * v); + +int gsl_vector_uint_swap (gsl_vector_uint * v, gsl_vector_uint * w); +int gsl_vector_uint_swap_elements (gsl_vector_uint * v, const size_t i, const size_t j); + +unsigned int gsl_vector_uint_max (const gsl_vector_uint * v); +unsigned int gsl_vector_uint_min (const gsl_vector_uint * v); +void gsl_vector_uint_minmax (const gsl_vector_uint * v, unsigned int * min_out, unsigned int * max_out); + +size_t gsl_vector_uint_max_index (const gsl_vector_uint * v); +size_t gsl_vector_uint_min_index (const gsl_vector_uint * v); +void gsl_vector_uint_minmax_index (const gsl_vector_uint * v, size_t * imin, size_t * imax); + +int gsl_vector_uint_add (gsl_vector_uint * a, const gsl_vector_uint * b); +int gsl_vector_uint_sub (gsl_vector_uint * a, const gsl_vector_uint * b); +int gsl_vector_uint_mul (gsl_vector_uint * a, const gsl_vector_uint * b); +int gsl_vector_uint_div (gsl_vector_uint * a, const gsl_vector_uint * b); +int gsl_vector_uint_scale (gsl_vector_uint * a, const unsigned int x); +int gsl_vector_uint_add_constant (gsl_vector_uint * a, const unsigned int x); +int gsl_vector_uint_axpby (const unsigned int alpha, const gsl_vector_uint * x, const unsigned int beta, gsl_vector_uint * y); +unsigned int gsl_vector_uint_sum (const gsl_vector_uint * a); + +int gsl_vector_uint_equal (const gsl_vector_uint * u, + const gsl_vector_uint * v); + +int gsl_vector_uint_isnull (const gsl_vector_uint * v); +int gsl_vector_uint_ispos (const gsl_vector_uint * v); +int gsl_vector_uint_isneg (const gsl_vector_uint * v); +int gsl_vector_uint_isnonneg (const gsl_vector_uint * v); + +INLINE_DECL unsigned int gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i); +INLINE_DECL void gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x); +INLINE_DECL unsigned int * gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i); +INLINE_DECL const unsigned int * gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +unsigned int +gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +unsigned int * +gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (unsigned int *) (v->data + i * v->stride); +} + +INLINE_FUN +const unsigned int * +gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const unsigned int *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_UINT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ulong.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ulong.h new file mode 100644 index 0000000..4f4c254 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ulong.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_ulong.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_ULONG_H__ +#define __GSL_VECTOR_ULONG_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + unsigned long *data; + gsl_block_ulong *block; + int owner; +} +gsl_vector_ulong; + +typedef struct +{ + gsl_vector_ulong vector; +} _gsl_vector_ulong_view; + +typedef _gsl_vector_ulong_view gsl_vector_ulong_view; + +typedef struct +{ + gsl_vector_ulong vector; +} _gsl_vector_ulong_const_view; + +typedef const _gsl_vector_ulong_const_view gsl_vector_ulong_const_view; + + +/* Allocation */ + +gsl_vector_ulong *gsl_vector_ulong_alloc (const size_t n); +gsl_vector_ulong *gsl_vector_ulong_calloc (const size_t n); + +gsl_vector_ulong *gsl_vector_ulong_alloc_from_block (gsl_block_ulong * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_ulong *gsl_vector_ulong_alloc_from_vector (gsl_vector_ulong * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_ulong_free (gsl_vector_ulong * v); + +/* Views */ + +_gsl_vector_ulong_view +gsl_vector_ulong_view_array (unsigned long *v, size_t n); + +_gsl_vector_ulong_view +gsl_vector_ulong_view_array_with_stride (unsigned long *base, + size_t stride, + size_t n); + +_gsl_vector_ulong_const_view +gsl_vector_ulong_const_view_array (const unsigned long *v, size_t n); + +_gsl_vector_ulong_const_view +gsl_vector_ulong_const_view_array_with_stride (const unsigned long *base, + size_t stride, + size_t n); + +_gsl_vector_ulong_view +gsl_vector_ulong_subvector (gsl_vector_ulong *v, + size_t i, + size_t n); + +_gsl_vector_ulong_view +gsl_vector_ulong_subvector_with_stride (gsl_vector_ulong *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_ulong_const_view +gsl_vector_ulong_const_subvector (const gsl_vector_ulong *v, + size_t i, + size_t n); + +_gsl_vector_ulong_const_view +gsl_vector_ulong_const_subvector_with_stride (const gsl_vector_ulong *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_ulong_set_zero (gsl_vector_ulong * v); +void gsl_vector_ulong_set_all (gsl_vector_ulong * v, unsigned long x); +int gsl_vector_ulong_set_basis (gsl_vector_ulong * v, size_t i); + +int gsl_vector_ulong_fread (FILE * stream, gsl_vector_ulong * v); +int gsl_vector_ulong_fwrite (FILE * stream, const gsl_vector_ulong * v); +int gsl_vector_ulong_fscanf (FILE * stream, gsl_vector_ulong * v); +int gsl_vector_ulong_fprintf (FILE * stream, const gsl_vector_ulong * v, + const char *format); + +int gsl_vector_ulong_memcpy (gsl_vector_ulong * dest, const gsl_vector_ulong * src); + +int gsl_vector_ulong_reverse (gsl_vector_ulong * v); + +int gsl_vector_ulong_swap (gsl_vector_ulong * v, gsl_vector_ulong * w); +int gsl_vector_ulong_swap_elements (gsl_vector_ulong * v, const size_t i, const size_t j); + +unsigned long gsl_vector_ulong_max (const gsl_vector_ulong * v); +unsigned long gsl_vector_ulong_min (const gsl_vector_ulong * v); +void gsl_vector_ulong_minmax (const gsl_vector_ulong * v, unsigned long * min_out, unsigned long * max_out); + +size_t gsl_vector_ulong_max_index (const gsl_vector_ulong * v); +size_t gsl_vector_ulong_min_index (const gsl_vector_ulong * v); +void gsl_vector_ulong_minmax_index (const gsl_vector_ulong * v, size_t * imin, size_t * imax); + +int gsl_vector_ulong_add (gsl_vector_ulong * a, const gsl_vector_ulong * b); +int gsl_vector_ulong_sub (gsl_vector_ulong * a, const gsl_vector_ulong * b); +int gsl_vector_ulong_mul (gsl_vector_ulong * a, const gsl_vector_ulong * b); +int gsl_vector_ulong_div (gsl_vector_ulong * a, const gsl_vector_ulong * b); +int gsl_vector_ulong_scale (gsl_vector_ulong * a, const unsigned long x); +int gsl_vector_ulong_add_constant (gsl_vector_ulong * a, const unsigned long x); +int gsl_vector_ulong_axpby (const unsigned long alpha, const gsl_vector_ulong * x, const unsigned long beta, gsl_vector_ulong * y); +unsigned long gsl_vector_ulong_sum (const gsl_vector_ulong * a); + +int gsl_vector_ulong_equal (const gsl_vector_ulong * u, + const gsl_vector_ulong * v); + +int gsl_vector_ulong_isnull (const gsl_vector_ulong * v); +int gsl_vector_ulong_ispos (const gsl_vector_ulong * v); +int gsl_vector_ulong_isneg (const gsl_vector_ulong * v); +int gsl_vector_ulong_isnonneg (const gsl_vector_ulong * v); + +INLINE_DECL unsigned long gsl_vector_ulong_get (const gsl_vector_ulong * v, const size_t i); +INLINE_DECL void gsl_vector_ulong_set (gsl_vector_ulong * v, const size_t i, unsigned long x); +INLINE_DECL unsigned long * gsl_vector_ulong_ptr (gsl_vector_ulong * v, const size_t i); +INLINE_DECL const unsigned long * gsl_vector_ulong_const_ptr (const gsl_vector_ulong * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +unsigned long +gsl_vector_ulong_get (const gsl_vector_ulong * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_ulong_set (gsl_vector_ulong * v, const size_t i, unsigned long x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +unsigned long * +gsl_vector_ulong_ptr (gsl_vector_ulong * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (unsigned long *) (v->data + i * v->stride); +} + +INLINE_FUN +const unsigned long * +gsl_vector_ulong_const_ptr (const gsl_vector_ulong * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const unsigned long *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_ULONG_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ushort.h b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ushort.h new file mode 100644 index 0000000..ce1ffae --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_vector_ushort.h @@ -0,0 +1,232 @@ +/* vector/gsl_vector_ushort.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_VECTOR_USHORT_H__ +#define __GSL_VECTOR_USHORT_H__ + +#include +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef struct +{ + size_t size; + size_t stride; + unsigned short *data; + gsl_block_ushort *block; + int owner; +} +gsl_vector_ushort; + +typedef struct +{ + gsl_vector_ushort vector; +} _gsl_vector_ushort_view; + +typedef _gsl_vector_ushort_view gsl_vector_ushort_view; + +typedef struct +{ + gsl_vector_ushort vector; +} _gsl_vector_ushort_const_view; + +typedef const _gsl_vector_ushort_const_view gsl_vector_ushort_const_view; + + +/* Allocation */ + +gsl_vector_ushort *gsl_vector_ushort_alloc (const size_t n); +gsl_vector_ushort *gsl_vector_ushort_calloc (const size_t n); + +gsl_vector_ushort *gsl_vector_ushort_alloc_from_block (gsl_block_ushort * b, + const size_t offset, + const size_t n, + const size_t stride); + +gsl_vector_ushort *gsl_vector_ushort_alloc_from_vector (gsl_vector_ushort * v, + const size_t offset, + const size_t n, + const size_t stride); + +void gsl_vector_ushort_free (gsl_vector_ushort * v); + +/* Views */ + +_gsl_vector_ushort_view +gsl_vector_ushort_view_array (unsigned short *v, size_t n); + +_gsl_vector_ushort_view +gsl_vector_ushort_view_array_with_stride (unsigned short *base, + size_t stride, + size_t n); + +_gsl_vector_ushort_const_view +gsl_vector_ushort_const_view_array (const unsigned short *v, size_t n); + +_gsl_vector_ushort_const_view +gsl_vector_ushort_const_view_array_with_stride (const unsigned short *base, + size_t stride, + size_t n); + +_gsl_vector_ushort_view +gsl_vector_ushort_subvector (gsl_vector_ushort *v, + size_t i, + size_t n); + +_gsl_vector_ushort_view +gsl_vector_ushort_subvector_with_stride (gsl_vector_ushort *v, + size_t i, + size_t stride, + size_t n); + +_gsl_vector_ushort_const_view +gsl_vector_ushort_const_subvector (const gsl_vector_ushort *v, + size_t i, + size_t n); + +_gsl_vector_ushort_const_view +gsl_vector_ushort_const_subvector_with_stride (const gsl_vector_ushort *v, + size_t i, + size_t stride, + size_t n); + +/* Operations */ + +void gsl_vector_ushort_set_zero (gsl_vector_ushort * v); +void gsl_vector_ushort_set_all (gsl_vector_ushort * v, unsigned short x); +int gsl_vector_ushort_set_basis (gsl_vector_ushort * v, size_t i); + +int gsl_vector_ushort_fread (FILE * stream, gsl_vector_ushort * v); +int gsl_vector_ushort_fwrite (FILE * stream, const gsl_vector_ushort * v); +int gsl_vector_ushort_fscanf (FILE * stream, gsl_vector_ushort * v); +int gsl_vector_ushort_fprintf (FILE * stream, const gsl_vector_ushort * v, + const char *format); + +int gsl_vector_ushort_memcpy (gsl_vector_ushort * dest, const gsl_vector_ushort * src); + +int gsl_vector_ushort_reverse (gsl_vector_ushort * v); + +int gsl_vector_ushort_swap (gsl_vector_ushort * v, gsl_vector_ushort * w); +int gsl_vector_ushort_swap_elements (gsl_vector_ushort * v, const size_t i, const size_t j); + +unsigned short gsl_vector_ushort_max (const gsl_vector_ushort * v); +unsigned short gsl_vector_ushort_min (const gsl_vector_ushort * v); +void gsl_vector_ushort_minmax (const gsl_vector_ushort * v, unsigned short * min_out, unsigned short * max_out); + +size_t gsl_vector_ushort_max_index (const gsl_vector_ushort * v); +size_t gsl_vector_ushort_min_index (const gsl_vector_ushort * v); +void gsl_vector_ushort_minmax_index (const gsl_vector_ushort * v, size_t * imin, size_t * imax); + +int gsl_vector_ushort_add (gsl_vector_ushort * a, const gsl_vector_ushort * b); +int gsl_vector_ushort_sub (gsl_vector_ushort * a, const gsl_vector_ushort * b); +int gsl_vector_ushort_mul (gsl_vector_ushort * a, const gsl_vector_ushort * b); +int gsl_vector_ushort_div (gsl_vector_ushort * a, const gsl_vector_ushort * b); +int gsl_vector_ushort_scale (gsl_vector_ushort * a, const unsigned short x); +int gsl_vector_ushort_add_constant (gsl_vector_ushort * a, const unsigned short x); +int gsl_vector_ushort_axpby (const unsigned short alpha, const gsl_vector_ushort * x, const unsigned short beta, gsl_vector_ushort * y); +unsigned short gsl_vector_ushort_sum (const gsl_vector_ushort * a); + +int gsl_vector_ushort_equal (const gsl_vector_ushort * u, + const gsl_vector_ushort * v); + +int gsl_vector_ushort_isnull (const gsl_vector_ushort * v); +int gsl_vector_ushort_ispos (const gsl_vector_ushort * v); +int gsl_vector_ushort_isneg (const gsl_vector_ushort * v); +int gsl_vector_ushort_isnonneg (const gsl_vector_ushort * v); + +INLINE_DECL unsigned short gsl_vector_ushort_get (const gsl_vector_ushort * v, const size_t i); +INLINE_DECL void gsl_vector_ushort_set (gsl_vector_ushort * v, const size_t i, unsigned short x); +INLINE_DECL unsigned short * gsl_vector_ushort_ptr (gsl_vector_ushort * v, const size_t i); +INLINE_DECL const unsigned short * gsl_vector_ushort_const_ptr (const gsl_vector_ushort * v, const size_t i); + +#ifdef HAVE_INLINE + +INLINE_FUN +unsigned short +gsl_vector_ushort_get (const gsl_vector_ushort * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0); + } +#endif + return v->data[i * v->stride]; +} + +INLINE_FUN +void +gsl_vector_ushort_set (gsl_vector_ushort * v, const size_t i, unsigned short x) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_VOID ("index out of range", GSL_EINVAL); + } +#endif + v->data[i * v->stride] = x; +} + +INLINE_FUN +unsigned short * +gsl_vector_ushort_ptr (gsl_vector_ushort * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (unsigned short *) (v->data + i * v->stride); +} + +INLINE_FUN +const unsigned short * +gsl_vector_ushort_const_ptr (const gsl_vector_ushort * v, const size_t i) +{ +#if GSL_RANGE_CHECK + if (GSL_RANGE_COND(i >= v->size)) + { + GSL_ERROR_NULL ("index out of range", GSL_EINVAL); + } +#endif + return (const unsigned short *) (v->data + i * v->stride); +} +#endif /* HAVE_INLINE */ + +__END_DECLS + +#endif /* __GSL_VECTOR_USHORT_H__ */ + + diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_version.h b/ChaosDataPlayer/GSL/include/gsl/gsl_version.h new file mode 100644 index 0000000..d5337be --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_version.h @@ -0,0 +1,26 @@ +#ifndef __GSL_VERSION_H__ +#define __GSL_VERSION_H__ + +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif +__BEGIN_DECLS + + +#define GSL_VERSION "2.7" +#define GSL_MAJOR_VERSION 2 +#define GSL_MINOR_VERSION 7 + +GSL_VAR const char * gsl_version; + +__END_DECLS + +#endif /* __GSL_VERSION_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet.h b/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet.h new file mode 100644 index 0000000..5e1ec2b --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet.h @@ -0,0 +1,100 @@ +/* wavelet/gsl_wavelet.h + * + * Copyright (C) 2004 Ivo Alxneit + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_WAVELET_H__ +#define __GSL_WAVELET_H__ +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +typedef enum { + gsl_wavelet_forward = 1, gsl_wavelet_backward = -1 +} +gsl_wavelet_direction; + +typedef struct +{ + const char *name; + int (*init) (const double **h1, const double **g1, + const double **h2, const double **g2, size_t * nc, + size_t * offset, size_t member); +} +gsl_wavelet_type; + +typedef struct +{ + const gsl_wavelet_type *type; + const double *h1; + const double *g1; + const double *h2; + const double *g2; + size_t nc; + size_t offset; +} +gsl_wavelet; + +typedef struct +{ + double *scratch; + size_t n; +} +gsl_wavelet_workspace; + +GSL_VAR const gsl_wavelet_type *gsl_wavelet_daubechies; +GSL_VAR const gsl_wavelet_type *gsl_wavelet_daubechies_centered; +GSL_VAR const gsl_wavelet_type *gsl_wavelet_haar; +GSL_VAR const gsl_wavelet_type *gsl_wavelet_haar_centered; +GSL_VAR const gsl_wavelet_type *gsl_wavelet_bspline; +GSL_VAR const gsl_wavelet_type *gsl_wavelet_bspline_centered; + +gsl_wavelet *gsl_wavelet_alloc (const gsl_wavelet_type * T, size_t k); +void gsl_wavelet_free (gsl_wavelet * w); +const char *gsl_wavelet_name (const gsl_wavelet * w); + +gsl_wavelet_workspace *gsl_wavelet_workspace_alloc (size_t n); +void gsl_wavelet_workspace_free (gsl_wavelet_workspace * work); + +int gsl_wavelet_transform (const gsl_wavelet * w, + double *data, size_t stride, size_t n, + gsl_wavelet_direction dir, + gsl_wavelet_workspace * work); + +int gsl_wavelet_transform_forward (const gsl_wavelet * w, + double *data, size_t stride, size_t n, + gsl_wavelet_workspace * work); + +int gsl_wavelet_transform_inverse (const gsl_wavelet * w, + double *data, size_t stride, size_t n, + gsl_wavelet_workspace * work); + +__END_DECLS + +#endif /* __GSL_WAVELET_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet2d.h b/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet2d.h new file mode 100644 index 0000000..173f43e --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/gsl_wavelet2d.h @@ -0,0 +1,107 @@ +/* wavelet/gsl_wavelet.h + * + * Copyright (C) 2004 Ivo Alxneit + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_WAVELET2D_H__ +#define __GSL_WAVELET2D_H__ +#include +#include +#include +#include +#include + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_wavelet2d_transform (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_direction dir, + gsl_wavelet_workspace * work); + +int gsl_wavelet2d_transform_forward (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_workspace * work); + +int gsl_wavelet2d_transform_inverse (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_workspace * work); + +int gsl_wavelet2d_nstransform (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_direction dir, + gsl_wavelet_workspace * work); + +int gsl_wavelet2d_nstransform_forward (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_workspace * work); + +int gsl_wavelet2d_nstransform_inverse (const gsl_wavelet * w, + double *data, + size_t tda, size_t size1, size_t size2, + gsl_wavelet_workspace * work); + +int +gsl_wavelet2d_transform_matrix (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_direction dir, + gsl_wavelet_workspace * work); + +int +gsl_wavelet2d_transform_matrix_forward (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_workspace * work); + +int +gsl_wavelet2d_transform_matrix_inverse (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_workspace * work); + + +int +gsl_wavelet2d_nstransform_matrix (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_direction dir, + gsl_wavelet_workspace * work); + +int +gsl_wavelet2d_nstransform_matrix_forward (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_workspace * work); + +int +gsl_wavelet2d_nstransform_matrix_inverse (const gsl_wavelet * w, + gsl_matrix * a, + gsl_wavelet_workspace * work); + +__END_DECLS + +#endif /* __GSL_WAVELET2D_H__ */ diff --git a/ChaosDataPlayer/GSL/include/gsl/test_source.c b/ChaosDataPlayer/GSL/include/gsl/test_source.c new file mode 100644 index 0000000..bb72486 --- /dev/null +++ b/ChaosDataPlayer/GSL/include/gsl/test_source.c @@ -0,0 +1,262 @@ +/* complex/test_source.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough + * Copyright (C) 2021 Patrick Alken + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +struct f +{ + char *name; + double (*f) (gsl_complex z); + double x; + double y; + double fx; + double fy; +}; + +struct fz +{ + char *name; + gsl_complex (*f) (gsl_complex z); + double x; + double y; + double fx; + double fy; +}; + +struct fzz +{ + char *name; + gsl_complex (*f) (gsl_complex z1, gsl_complex z2); + double x1; + double y1; + double x2; + double y2; + double fx; + double fy; +}; + + +struct freal +{ + char *name; + gsl_complex (*f) (double x); + double x; + double fx; + double fy; +}; + +struct fzreal +{ + char *name; + gsl_complex (*f) (gsl_complex z, double a); + double x; + double y; + double a; + double fx; + double fy; +}; + +#define FN(x) "gsl_complex_" #x, gsl_complex_ ## x +#define ARG(x,y) x, y +#define RES(x,y) x, y + +struct f list[] = +{ +#include "results1.h" + {"", 0, 0, 0, 0, 0} +}; + + +struct fz listz[] = +{ +#include "results.h" + {"", 0, 0, 0, 0, 0} +}; + +struct fzz listzz[] = +{ + {FN (pow), ARG(0.0,0.0), ARG(0.0,0.0), RES(1.0, 0.0)}, +#include "results2.h" + {"", 0, 0, 0, 0, 0, 0, 0} +}; + +struct freal listreal[] = +{ +#include "results_real.h" + {"", 0, 0, 0, 0} +}; + + +struct fzreal listzreal[] = +{ +#include "results_zreal.h" + {"", 0, 0, 0, 0, 0, 0} +}; + + +#ifndef TEST_FACTOR +#ifdef RELEASED +#define TEST_FACTOR 100.0 +#else +#define TEST_FACTOR 1.0 +#endif +#endif + +static int +FUNCTION (test, all) () +{ + size_t i = 0; +#if defined(BASE_DOUBLE) + const double tol = GSL_DBL_EPSILON; +#endif + + gsl_ieee_env_setup(); + + for (i = 0 ; i < 10; i++) + { + ATOMIC x = (i - 5.0) * 0.3; + ATOMIC y = (i + 2.1) * 0.5; + TYPE(gsl_complex) z = gsl_complex_rect(x, y); + + gsl_test_rel (GSL_REAL(z), x, tol, "gsl_complex_rect real part at (x=%g,y=%g)", x, y); + gsl_test_rel (GSL_IMAG(z), y, tol, "gsl_complex_rect imag part at (x=%g,y=%g)", x, y); + + GSL_REAL(z) = y; + gsl_test_rel (GSL_REAL(z), y, tol, "assignment real part (%g)", y); + + GSL_IMAG(z) = x; + gsl_test_rel (GSL_IMAG(z), x, tol, "assignment imag part (%g)", x); + } + + for (i = 0 ; i < 10; i++) + { + ATOMIC r = (i - 5.0) * 0.3 ; + ATOMIC t = 2.0 * M_PI * i / 5 ; + ATOMIC x = r * cos(t), y = r * sin(t) ; + TYPE(gsl_complex) z = gsl_complex_polar (r, t) ; + gsl_test_rel (GSL_REAL(z), x, tol, "gsl_complex_polar real part at (r=%g,t=%g)", r, t); + gsl_test_rel (GSL_IMAG(z), y, tol, "gsl_complex_polar imag part at (r=%g,t=%g)", r, t); + } + + i = 0; + + while (list[i].f) + { + struct f t = list[i]; + TYPE(gsl_complex) z = gsl_complex_rect (t.x, t.y); + ATOMIC f = (t.f) (z); + gsl_test_rel (f, t.fx, tol, "%s at (%g,%g)", t.name, t.x, t.y); + i++; + } + + i = 0; + + while (listz[i].f) + { + struct fz t = listz[i]; + TYPE(gsl_complex) z = gsl_complex_rect (t.x, t.y); + TYPE(gsl_complex) fz = (t.f) (z); + ATOMIC fx = GSL_REAL (fz), fy = GSL_IMAG (fz); + +#ifdef DEBUG + printf("x = "); gsl_ieee_fprintf_double (stdout, &t.x); printf("\n"); + printf("y = "); gsl_ieee_fprintf_double (stdout, &t.y); printf("\n"); + printf("fx = "); gsl_ieee_fprintf_double (stdout, &fx); printf("\n"); + printf("ex = "); gsl_ieee_fprintf_double (stdout, &t.fx); printf("\n"); + printf("fy = "); gsl_ieee_fprintf_double (stdout, &fy); printf("\n"); + printf("ey = "); gsl_ieee_fprintf_double (stdout, &t.fy); printf("\n"); +#endif + + gsl_test_rel (fx, t.fx, 10.0 * tol, "%s real part at (%g,%g)", t.name, t.x, t.y); + gsl_test_rel (fy, t.fy, 10.0 * tol, "%s imag part at (%g,%g)", t.name, t.x, t.y); + i++; + } + + i = 0; + + while (listzz[i].f) + { + struct fzz t = listzz[i]; + TYPE(gsl_complex) z1 = gsl_complex_rect (t.x1, t.y1); + TYPE(gsl_complex) z2 = gsl_complex_rect (t.x2, t.y2); + TYPE(gsl_complex) fz = (t.f) (z1, z2); + ATOMIC fx = GSL_REAL (fz), fy = GSL_IMAG (fz); + +#ifdef DEBUG + printf("x1 = "); gsl_ieee_fprintf_double (stdout, &t.x1); printf("\n"); + printf("y1 = "); gsl_ieee_fprintf_double (stdout, &t.y1); printf("\n"); + printf("x2 = "); gsl_ieee_fprintf_double (stdout, &t.x2); printf("\n"); + printf("y2 = "); gsl_ieee_fprintf_double (stdout, &t.y2); printf("\n"); + printf("fx = "); gsl_ieee_fprintf_double (stdout, &fx); printf("\n"); + printf("ex = "); gsl_ieee_fprintf_double (stdout, &t.fx); printf("\n"); + printf("fy = "); gsl_ieee_fprintf_double (stdout, &fy); printf("\n"); + printf("ey = "); gsl_ieee_fprintf_double (stdout, &t.fy); printf("\n"); +#endif + + gsl_test_rel (fx, t.fx, 1.0e3 * tol, "%s real part at (%g,%g;%g,%g)", t.name, t.x1, t.y1, t.x2, t.y2); + gsl_test_rel (fy, t.fy, 1.0e3 * tol, "%s imag part at (%g,%g;%g,%g)", t.name, t.x1, t.y1, t.x2, t.y2); + i++; + } + + i = 0; + + while (listreal[i].f) + { + struct freal t = listreal[i]; + TYPE(gsl_complex) fz = (t.f) (t.x); + ATOMIC fx = GSL_REAL (fz), fy = GSL_IMAG (fz); + +#ifdef DEBUG + printf("x = "); gsl_ieee_fprintf_double (stdout, &t.x); printf("\n"); + printf("fx = "); gsl_ieee_fprintf_double (stdout, &fx); printf("\n"); + printf("ex = "); gsl_ieee_fprintf_double (stdout, &t.fx); printf("\n"); + printf("fy = "); gsl_ieee_fprintf_double (stdout, &fy); printf("\n"); + printf("ey = "); gsl_ieee_fprintf_double (stdout, &t.fy); printf("\n"); +#endif + + gsl_test_rel (fx, t.fx, tol, "%s real part at (%g,0)", t.name, t.x); + gsl_test_rel (fy, t.fy, tol, "%s imag part at (%g,0)", t.name, t.x); + i++; + } + + i = 0; + + while (listzreal[i].f) + { + struct fzreal t = listzreal[i]; + TYPE(gsl_complex) z = gsl_complex_rect (t.x, t.y); + TYPE(gsl_complex) fz = (t.f) (z, t.a); + ATOMIC fx = GSL_REAL (fz), fy = GSL_IMAG (fz); + +#ifdef DEBUG + printf("x = "); gsl_ieee_fprintf_double (stdout, &t.x); printf("\n"); + printf("y = "); gsl_ieee_fprintf_double (stdout, &t.y); printf("\n"); + printf("a = "); gsl_ieee_fprintf_double (stdout, &t.a); printf("\n"); + printf("fx = "); gsl_ieee_fprintf_double (stdout, &fx); printf("\n"); + printf("ex = "); gsl_ieee_fprintf_double (stdout, &t.fx); printf("\n"); + printf("fy = "); gsl_ieee_fprintf_double (stdout, &fy); printf("\n"); + printf("ey = "); gsl_ieee_fprintf_double (stdout, &t.fy); printf("\n"); +#endif + + gsl_test_rel (fx, t.fx, 10.0 * tol, "%s real part at (%g,0)", t.name, t.x); + gsl_test_rel (fy, t.fy, 10.0 * tol, "%s imag part at (%g,0)", t.name, t.x); + i++; + } + + return 0; +} diff --git a/ChaosDataPlayer/GSL/lib/libgsl.a b/ChaosDataPlayer/GSL/lib/libgsl.a new file mode 100644 index 0000000..0c311d2 Binary files /dev/null and b/ChaosDataPlayer/GSL/lib/libgsl.a differ diff --git a/ChaosDataPlayer/GSL/lib/libgsl.dll.a b/ChaosDataPlayer/GSL/lib/libgsl.dll.a new file mode 100644 index 0000000..4095212 Binary files /dev/null and b/ChaosDataPlayer/GSL/lib/libgsl.dll.a differ diff --git a/ChaosDataPlayer/GSL/lib/libgsl.la b/ChaosDataPlayer/GSL/lib/libgsl.la new file mode 100644 index 0000000..72e5b9f --- /dev/null +++ b/ChaosDataPlayer/GSL/lib/libgsl.la @@ -0,0 +1,41 @@ +# libgsl.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='../bin/libgsl-25.dll' + +# Names of this library. +library_names='libgsl.dll.a' + +# The name of the static archive. +old_library='libgsl.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs=' /usr/local/lib/libgslcblas.la' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libgsl. +current=26 +age=1 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/ChaosDataPlayer/GSL/lib/libgslcblas.a b/ChaosDataPlayer/GSL/lib/libgslcblas.a new file mode 100644 index 0000000..6b8c714 Binary files /dev/null and b/ChaosDataPlayer/GSL/lib/libgslcblas.a differ diff --git a/ChaosDataPlayer/GSL/lib/libgslcblas.dll.a b/ChaosDataPlayer/GSL/lib/libgslcblas.dll.a new file mode 100644 index 0000000..c15ea1f Binary files /dev/null and b/ChaosDataPlayer/GSL/lib/libgslcblas.dll.a differ diff --git a/ChaosDataPlayer/GSL/lib/libgslcblas.la b/ChaosDataPlayer/GSL/lib/libgslcblas.la new file mode 100644 index 0000000..101e855 --- /dev/null +++ b/ChaosDataPlayer/GSL/lib/libgslcblas.la @@ -0,0 +1,41 @@ +# libgslcblas.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4.6 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='../bin/libgslcblas-0.dll' + +# Names of this library. +library_names='libgslcblas.dll.a' + +# The name of the static archive. +old_library='libgslcblas.a' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='' + +# Libraries that this one depends upon. +dependency_libs='' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libgslcblas. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=yes + +# Should we warn about portability when linking against -modules? +shouldnotlink=no + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/local/lib' diff --git a/ChaosDataPlayer/GSL/lib/pkgconfig/gsl.pc b/ChaosDataPlayer/GSL/lib/pkgconfig/gsl.pc new file mode 100644 index 0000000..ccf6ebe --- /dev/null +++ b/ChaosDataPlayer/GSL/lib/pkgconfig/gsl.pc @@ -0,0 +1,11 @@ +prefix=/usr/local +exec_prefix=/usr/local +libdir=/usr/local/lib +includedir=/usr/local/include +GSL_CBLAS_LIB=-lgslcblas + +Name: GSL +Description: GNU Scientific Library +Version: 2.7 +Libs: -L/usr/local/lib -lgsl ${GSL_CBLAS_LIB} -lm -lm +Cflags: -I/usr/local/include diff --git a/ChaosDataPlayer/ICON.ico b/ChaosDataPlayer/ICON.ico new file mode 100644 index 0000000..c37c58e Binary files /dev/null and b/ChaosDataPlayer/ICON.ico differ diff --git a/ChaosDataPlayer/ICON.rc b/ChaosDataPlayer/ICON.rc new file mode 100644 index 0000000..4aada6a --- /dev/null +++ b/ChaosDataPlayer/ICON.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "ICON.ico" \ No newline at end of file diff --git a/ChaosDataPlayer/LegendForm.cpp b/ChaosDataPlayer/LegendForm.cpp new file mode 100644 index 0000000..42e0619 --- /dev/null +++ b/ChaosDataPlayer/LegendForm.cpp @@ -0,0 +1,78 @@ +#include "LegendForm.h" +#include "ui_LegendForm.h" + +#include +#include + +#define CHAID_ROLE (Qt::UserRole + 2) + +LegendForm::LegendForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::LegendForm) +{ + ui->setupUi(m_pMainWgt); + setWindowFlags(Qt::Window | Qt::FramelessWindowHint); + setCloseBtnVisible(false); + + Init(); +} + +LegendForm::~LegendForm() +{ + delete ui; +} + +void LegendForm::SetChannelIDs(const QStringList &strIDList) +{ + //clear table + for (int i = 0; i < ui->tableWidget->rowCount(); ++i) + { + QTableWidgetItem *pItem = ui->tableWidget->itemAt(i, 0); + QTableWidgetItem *pItem1 = ui->tableWidget->itemAt(i, 1); + + if(pItem) delete pItem; + if(pItem1) delete pItem1; + } + ui->tableWidget->clearContents(); + ui->tableWidget->setRowCount(0); + + m_strIDList = strIDList; + foreach(QString strID, strIDList) + { + QString strNum1 = strID.right(2).left(1); + QString strNum2 = strID.right(1); + QString strText = QStringLiteral("第%1板卡第%2通道").arg(strNum1).arg(strNum2); + QTableWidgetItem*pItem = AddTableWgtItem(strText, strID); + pItem->setData(CHAID_ROLE, strID); + } +} + +void LegendForm::SetValue(QString strID, QString strValue) +{ + qDebug()<<"LegendForm::SetValue"<setText(strValue); +} + +void LegendForm::Init() +{ + ui->tableWidget->setColumnCount(2); + + ui->tableWidget->setColumnWidth(0, 120); +} + +QTableWidgetItem *LegendForm::AddTableWgtItem(QString strText, QString strID) +{ + ui->tableWidget->setRowCount(ui->tableWidget->rowCount() + 1); + QTableWidgetItem *pItemName = new QTableWidgetItem(); + pItemName->setText(strText); + QTableWidgetItem *pItemValue = new QTableWidgetItem(); + pItemValue->setText(""); + + ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 0, pItemName); + ui->tableWidget->setItem(ui->tableWidget->rowCount() - 1, 1, pItemValue); + qDebug()<<"LegendForm::AddTableWgtItem:::::::"<tableWidget->rowCount() - 1< +#include +#include "BaseWgt.h" + +class QTableWidgetItem; + +namespace Ui { +class LegendForm; +} + +class LegendForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit LegendForm(QWidget *parent = nullptr); + ~LegendForm(); + + void SetChannelIDs(const QStringList &strIDList); + + void SetValue(QString strID, QString strValue); +private: + void Init(); + + QTableWidgetItem * AddTableWgtItem(QString strText, QString strID); +private: + Ui::LegendForm *ui; + + QStringList m_strIDList; + QMap m_mapChannelIDtoItem; +}; + +#endif // LEGENDFORM_H diff --git a/ChaosDataPlayer/LegendForm.ui b/ChaosDataPlayer/LegendForm.ui new file mode 100644 index 0000000..45dc484 --- /dev/null +++ b/ChaosDataPlayer/LegendForm.ui @@ -0,0 +1,81 @@ + + + LegendForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + #tableWidget +{ + background:transparent; + border-top: 2px solid #50707f; + +} + +#tableWidget::item +{ + height: 24px; + border-width: 1; +} +#tableWidget::item:hover +{ + border: none; +} +#tableWidget::item:selected +{ + border: none; + color:#ffa405; +} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 400 + 300 + + + + false + + + true + + + false + + + false + + + + + + + + diff --git a/ChaosDataPlayer/LoadingDialog.cpp b/ChaosDataPlayer/LoadingDialog.cpp new file mode 100644 index 0000000..5f3fa99 --- /dev/null +++ b/ChaosDataPlayer/LoadingDialog.cpp @@ -0,0 +1,141 @@ +#pragma execution_character_set("utf-8") +#include "LoadingDialog.h" + +LoadingDialog::LoadingDialog(QWidget *parent) : QDialog(parent) +{ + //如果需要显示任务栏对话框则删除Qt::Tool + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint); + setAttribute(Qt::WA_TranslucentBackground, true); + initUi(); +} + +/** + * @brief LoadingDialog::initUi UI元素初始化 + */ +void LoadingDialog::initUi() +{ + this->setFixedSize(500, 360); + m_pCenterFrame = new QFrame(this); + m_pCenterFrame->setGeometry(0, 0 ,500, 360); + + //加载Loading动画 + m_pLoadingMovie = new QMovie(":/images/images/loading.gif"); + m_pLoadingMovie->setScaledSize(QSize(500, 300)); + m_pMovieLabel = new QLabel(m_pCenterFrame); + m_pMovieLabel->setGeometry(0, 0, 500, 300); + m_pMovieLabel->setScaledContents(true); + m_pMovieLabel->setMovie(m_pLoadingMovie); + m_pLoadingMovie->start(); + + //提示文本 + m_pTipsLabel = new QLabel(m_pCenterFrame); + m_pTipsLabel->setGeometry(300, 300, 200, 50); + m_pTipsLabel->setAlignment(Qt::AlignCenter | Qt::AlignHCenter); + m_pTipsLabel->setObjectName("tips"); + m_pTipsLabel->setText("版本号:V1.0"); + m_pTipsLabel->setStyleSheet("QLabel#tips{font-family:\"Microsoft YaHei\";font-size: 15px;color: #333333;}"); + + //取消按钮 + /*m_pCancelBtn = new QPushButton(m_pCenterFrame); + m_pCancelBtn->setObjectName("cancelBtn"); + m_pCancelBtn->setText("取消等待"); + m_pCancelBtn->setStyleSheet("QPushButton#cancelBtn{" + "background-color: #edeef6;" + "border-radius: 4px;" + "font-family: \"Microsoft YaHei\";" + "font-size: 14px;" + "color: #333333;" + "}" + "QPushButton#cancelBtn::hover{" + "background:#dcdeea" + "}"); + m_pCancelBtn->setGeometry(25, 180, 180, 35); + m_pCancelBtn->setEnabled(true); + connect(m_pCancelBtn, &QPushButton::clicked, this, &LoadingDialog::cancelBtnClicked);*/ + + //实例阴影shadow + QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); + shadow->setOffset(0, 0); + shadow->setColor(QColor(32, 101, 165)); + shadow->setBlurRadius(10); + this->setGraphicsEffect(shadow); +} + +/** + * @brief LoadingDialog::setTipsText 设置提示文本 + * @param strTipsText 提示文本 + */ +void LoadingDialog::setTipsText(QString strTipsText) +{ + m_pTipsLabel->setText(strTipsText); +} + +/** + * @brief LoadingDialog::setCanCancel 设置是够允许用户点击取消等待按钮 + * @param bCanCancel 是够允许 + */ +void LoadingDialog::setCanCancel(bool bCanCancel) +{ + m_pCancelBtn->setEnabled(bCanCancel); +} + +/** + * @brief LoadingDialog::moveToCenter 移动对话框到指定窗口中间 + * @param pParent 指定窗口指针 + */ +void LoadingDialog::moveToCenter(QWidget *pParent) +{ + if(pParent != nullptr && pParent != NULL) + { + int nParentWidth = pParent->width(); + int nParentHeigth = pParent->height(); + + int nWidth = this->width(); + int nHeight = this->height(); + + int nParentX = pParent->x(); + int nParentY = pParent->y(); + + int x = (nParentX + (nParentWidth - nWidth) / 2); + int y = (nParentY + (nParentHeigth - nHeight) / 2); + + this->move(x, y); + } +} + +/** + * @brief LoadingDialog::cancelBtnClicked 取消按钮槽函数 + */ +void LoadingDialog::cancelBtnClicked() +{ + emit cancelWaiting(); + this->done(USER_CANCEL); +} + +/** + * @brief LoadingDialog::paintEvent 界面绘制 + * @param event + */ +void LoadingDialog::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); //反锯齿 + painter.setBrush(QBrush(Qt::white)); + painter.setPen(Qt::transparent); + QRect rect = this->rect(); + rect.setLeft(9); + rect.setTop(9); + rect.setWidth(rect.width() - 9); + rect.setHeight(rect.height() - 9); + painter.drawRoundedRect(rect, 8, 8); + QWidget::paintEvent(event); +} + +LoadingDialog::~LoadingDialog() +{ + delete m_pLoadingMovie; + delete m_pMovieLabel; + delete m_pTipsLabel; + delete m_pCancelBtn; + delete m_pCenterFrame; +} diff --git a/ChaosDataPlayer/LoadingDialog.h b/ChaosDataPlayer/LoadingDialog.h new file mode 100644 index 0000000..1fc7acb --- /dev/null +++ b/ChaosDataPlayer/LoadingDialog.h @@ -0,0 +1,37 @@ +#ifndef LOADINGDIALOG_H +#define LOADINGDIALOG_H +#include +#include +#include +#include +#include +#include +#define USER_CANCEL -1 +class LoadingDialog : public QDialog +{ + Q_OBJECT +public: + explicit LoadingDialog(QWidget *parent = nullptr); + ~LoadingDialog(); + //设置提示文本 + void setTipsText(QString strTipsText); + //设置是否显示取消等待按钮 + void setCanCancel(bool bCanCancel); + //移动到指定窗口中间显示 + void moveToCenter(QWidget* pParent); +protected: + void paintEvent(QPaintEvent *event) override; +private: + void initUi(); +Q_SIGNALS: + void cancelWaiting(); +private slots: + void cancelBtnClicked(); +private: + QFrame *m_pCenterFrame; + QLabel *m_pMovieLabel; + QMovie *m_pLoadingMovie; + QLabel *m_pTipsLabel; + QPushButton *m_pCancelBtn; +}; +#endif // LOADINGDIALOG_H diff --git a/ChaosDataPlayer/MainWidget.cpp b/ChaosDataPlayer/MainWidget.cpp new file mode 100644 index 0000000..7fcb377 --- /dev/null +++ b/ChaosDataPlayer/MainWidget.cpp @@ -0,0 +1,2903 @@ +#include "MainWidget.h" +#include "ui_MainWidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ChildForm.h" +#include "Child3dFrom.h" +#include "cidwudp.h" +#include "NetMgr.h" +#include "msgbox.h" +#include + + + + + +DEVICE_INFO deviceInfo; + +#define FLAG_ROLE (Qt::UserRole + 2) +#define NO_ROLE (Qt::UserRole + 3) //存储设备号 +#define IP_ROLE (Qt::UserRole + 4) //存储ip +#define FILE_ROLE (Qt::UserRole + 5) //本地Dat + +int channelwork[32]; +int channelEnabled[32]; +bool AddFlag = false; +MainWidget::MainWidget(QWidget *parent) + : BaseWgt(parent) + , ui(new Ui::MainWidget) + +{ + ui->setupUi(m_pMainWgt); + resize(m_pMainWgt->size()); + setWindowTitle("Chaos Data Player"); + + m_iCurCount = 1; + m_backPlay = false; + Init(); + InitSignalandSlot(); + +} + +MainWidget::~MainWidget() +{ + if(m_pTimer) + { + m_pTimer->deleteLater(); + } + delete ui; +} +void MainWidget::Init() +{ + ui->treeWidget->expandAll(); + ui->treeWidget->setColumnCount(3); + ui->treeWidget->setColumnWidth(0, 700); + ui->treeWidget->setColumnWidth(1, 150); + ui->treeWidget->setColumnWidth(2, 160); + ui->tabWidget->setIconSize(QSize(30, 30)); + ui->tabWidget->setTabsClosable(false); + ui->splitter->setHandleWidth(1); + QList m_splitterLengths(ui->splitter->sizes()); + m_splitterLengths[0] = 200; + m_splitterLengths[1] = 500; + ui->splitter->setSizes(m_splitterLengths); + m_HideDevList = false; + + QString strCount = QString("%1/%2").arg(0).arg(0); + ui->label_value->setText(strCount); + ui->horizontalSlider->setRange(0,0); + + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(TimerSlot())); + + m_pCIDWUdp = new CIDWUdp(); + m_pThread = new QThread; + //移动到另一线程 + m_pCIDWUdp->moveToThread(m_pThread); + connect(m_pCIDWUdp, SIGNAL(RetSignal(QString,QString)), this, SLOT(RetSlot(QString,QString))); + //connect(m_pCIDWUdp, SIGNAL(IpSignal(QString)), this, SLOT(IpSlot(QString))); + connect(m_pThread, SIGNAL(finished()), m_pCIDWUdp, SLOT(deleteLater())); + m_pThread->start(); + + m_pNetMgr = new NetMgr(this); + + //设置拖动布局的初始比例 + + ui->splitter->setStretchFactor(0, 1); // widget gets 3 out of 4 width/height units + ui->splitter->setStretchFactor(1, 5); + + ui->tabWidget->setStyleSheet("QTabWidget#tabWidget{background-color:rgb(255,0,0);}\ + QTabBar::tab{background-color:rgb(58,63,72);color:rgb(170,195,207);font:12pt '新宋体'}\ + QTabBar::tab::selected{background-color:rgb(28,28,36);color:rgb(170,195,207);font:12pt '新宋体'}"); + + ui->Btn_Setting->setVisible(false); + InitDevList(); + +} +void MainWidget::InitDevList() +{ + int iRet = sql_db.OpenDataBase(); + qDebug() <<"iRet" <fileBtn, SIGNAL(clicked()), this, SLOT(OpenFileSlot())); //打开文件 + connect(ui->modelBtn_TrendChart, SIGNAL(clicked()), this, SLOT(TrendChartPlotSlot())); //趋势图 + connect(ui->modelBtn_TimeDomain, SIGNAL(clicked()), this, SLOT(TimeDomainPlotSlot())); //时域图 + connect(ui->modelBtn_spec, SIGNAL(clicked()), this, SLOT(FrequencyDomainPlotSlot())); //频域图 + connect(ui->modelBtn_env, SIGNAL(clicked()), this, SLOT(EnvelopeAnalysisPlotSlot())); //包络图 + connect(ui->modelBtn_4, SIGNAL(clicked()), this, SLOT(WaterFallPlotSlot())); //瀑布图 + connect(ui->modelBtn_7, SIGNAL(clicked()), this, SLOT(OrbitPlotSlot())); //轴心轨迹图图 + connect(ui->modelBtn_8, SIGNAL(clicked()), this, SLOT(PolarplotSlot())); //极坐标 + connect(ui->modelBtn_5, SIGNAL(clicked()), this, SLOT(BodePlotSlot())); + connect(ui->modelBtn_6, SIGNAL(clicked()), this, SLOT(ShaftCenterlinePlotSlot())); + connect(ui->modelBtn_12, SIGNAL(clicked()), this, SLOT(View3D())); + connect(ui->pushButton_5, SIGNAL(clicked()), this, SLOT(Dat2Csv())); + + connect(ui->refreshBtn, SIGNAL(clicked()), this, SLOT(RefreshBtnSlot()));//刷新终端列表 + connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(SlidervalueChangedSlot(int))); + connect(ui->PauseBtn, SIGNAL(clicked()), this, SLOT(PlayBtnSlot())); + connect(ui->backBtn, SIGNAL(clicked()), this, SLOT(Back1SBtnSlot())); + connect(ui->back2sBtn, SIGNAL(clicked()), this, SLOT(Back2SBtnSlot())); + connect(ui->back3sBtn, SIGNAL(clicked()), this, SLOT(Back3SBtnSlot())); + connect(ui->add1sBtn, SIGNAL(clicked()), this, SLOT(Add1SBtnSlot())); + connect(ui->add2sBtn, SIGNAL(clicked()), this, SLOT(Add2SBtnSlot())); + connect(ui->add3sBtn, SIGNAL(clicked()), this, SLOT(Add3SBtnSlot())); + connect(ui->addButton, SIGNAL(clicked()), this, SLOT(AddDevice())); + connect(ui->HideDev_Btn, SIGNAL(clicked()), this, SLOT(HideDev())); + connect(ui->ReportButton, SIGNAL(clicked()), this, SLOT(Report())); + connect(ui->pushButton_6, SIGNAL(clicked()), this, SLOT(ExitFile())); + connect(ui->Btn_Setting, SIGNAL(clicked()), this, SLOT(Setting())); + + + connect(ui->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem *,int)), this, SLOT(slotItemDoubleClicked(QTreeWidgetItem *, int ))); + //绑定HTTP消息响应 + connect(m_pNetMgr,SIGNAL(sigNetMgr(QString, const QVariant&)), this, SLOT(slotNetMgr(QString,const QVariant&))); + + ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); + bool a = QObject::connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this, &MainWidget::slotCustomContextMenuRequested); + ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); +} + +void MainWidget::slotItemDoubleClicked(QTreeWidgetItem *pItem, int column) +{ + if(pItem->parent() == NULL) + return; + if(pItem && pItem->parent()) + { + if(pItem->data(0, FLAG_ROLE).toString() == "config") + { + WebBtnSlot(pItem->parent()->text(0)); + return; + } + + } + if(pItem && pItem->parent() &&(pItem->parent()->data(0, FLAG_ROLE).value().contains("change") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("size") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("time") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("manu")) + ) + { + + { + + QString strData = pItem->parent()->data(0, FLAG_ROLE).value(); + QString strIP = pItem->parent()->parent()->parent()->data(0, IP_ROLE).value(); + qDebug()<<"MainWidget"<data(0,NO_ROLE).value(); + QString FileName = pItem->text(0); + qDebug()<<"MainWidget"<text(0); + QString datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNO + "\\" + strData + "\\"; + qDebug()<<"MainWidget"<treeWidget->clear(); + udp.writeDatagram(Cmd04,64,QHostAddress("224.0.0.1"), 7301); + } + else{ + QString whereCon = QString("DeviceIP = '%1'").arg(strIP); + QString tableName = "t_Device "; + QString column = "count(*)"; + int iRet = sql_db.QueryData(tableName,column,whereCon); + if(iRet >0){ + MyMsgBox(QMessageBox::Question,"警告","终端已经存在!"); + pAddDevice->close(); + delete pAddDevice; + return; + } + AddFlag = true; + udp.writeDatagram(Cmd04,64,QHostAddress(strIP), 7301); + } + qDebug() << "cmd:" << Cmd04; + +} +void MainWidget::RefreshBtnSlot() +{ + ui->treeWidget->clear(); + InitDevList(); + /*QString tablename = "t_Device"; + QString Col = "DeviceIP"; + array_t DevList = sql_db.GetDataMultiLine(tablename,Col,"Online = '0' "); + for(int i = 0 ; i < DevList.size();i++){ + QTreeWidgetItem *pTopItem = new QTreeWidgetItem(); + if(m_pNetMgr) + { + m_pNetMgr->RequestFileInfo(DevList[i][0]); + m_pNetMgr->RequestChannelInfo(DevList[i][0]); + } + }*/ +} +//输入ip返回IP节点下的数据节点 +QTreeWidgetItem *MainWidget::findDataItemByIP(QString sIP) +{ + int icount = ui->treeWidget->topLevelItemCount(); + for (int i = 0; i < icount; ++i) + { + QTreeWidgetItem *pTopItem = ui->treeWidget->topLevelItem(i); + if(!(pTopItem->text(0).contains(sIP))) continue; + + for (int j = 0; j < pTopItem->childCount(); ++j) + { + QTreeWidgetItem *pItem = pTopItem->child(j); + QString sFlag = pItem->data(0, FLAG_ROLE).value(); + if(sFlag.contains("data")) + { + return pItem; + } + } + } + + return nullptr; +} + +QTreeWidgetItem *MainWidget::findNameItemByIP(QString sIP) +{ + int icount = ui->treeWidget->topLevelItemCount(); + for (int i = 0; i < icount; ++i) + { + QTreeWidgetItem *pTopItem = ui->treeWidget->topLevelItem(i); + if(!(pTopItem->text(0).contains(sIP))) continue; + + for (int j = 0; j < pTopItem->childCount(); ++j) + { + QTreeWidgetItem *pItem = pTopItem->child(j); + QString sFlag = pItem->data(0, FLAG_ROLE).value(); + if(sFlag.contains("name")) + { + return pItem; + } + } + } + + return nullptr; +} +//根据设备IP,返回对应的WidgetItem +QTreeWidgetItem *MainWidget::findNOItemByIP(QString sIP) +{ + int icount = ui->treeWidget->topLevelItemCount(); + for (int i = 0; i < icount; ++i) + { + QTreeWidgetItem *pTopItem = ui->treeWidget->topLevelItem(i); + if(!(pTopItem->text(0).contains(sIP))) continue; + + for (int j = 0; j < pTopItem->childCount(); ++j) + { + QTreeWidgetItem *pItem = pTopItem->child(j); + QString sFlag = pItem->data(0, FLAG_ROLE).value(); + if(sFlag.contains("NO")) + { + return pItem; + } + } + } + + return nullptr; +} + +QString MainWidget::getServerAddrByEquipNo(QString sEquipNo) +{ + for (int iTop = 0; iTop treeWidget->topLevelItemCount(); ++iTop) + { + QTreeWidgetItem *pTopItem = ui->treeWidget->topLevelItem(iTop); + if(!pTopItem) continue; + for (int j = 0; j < pTopItem->childCount(); ++j) + { + QTreeWidgetItem *pItem = pTopItem->child(j); + QString sFlag = pItem->data(0, FLAG_ROLE).value(); + if(sFlag.contains("NO") && pItem->data(0,NO_ROLE).toString() == sEquipNo) + { + return pItem->parent()->data(0, IP_ROLE).toString(); + } + } + } + + return ""; +} +void MainWidget::slotNetMgr(QString sAddr, const QVariant &msg) +{ + QStringList sList = sAddr.split('+'); + if(sList.size() != 2) return; + + sAddr = sList.at(0); + if(sList.contains("RequestFileList")) + { + parseFileListData(sAddr, msg); + } + else if(sList.contains("RequestFileInfo")) + { + parseFileInfoData(sAddr, msg); + + }else if(sList.contains("RequestFileInfo")) + { + paraseChannelInfo(sAddr, msg); + } + QTreeWidgetItem *pDataItem = findDataItemByIP(sAddr); + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pDataItem->parent()->setIcon(0, icon); + +} +void MainWidget::parseFileListData(QString sAddr, const QVariant &msg) +{ + QTreeWidgetItem *pDataItem = findDataItemByIP(sAddr); + int iDataCount = pDataItem->childCount(); + + QTreeWidgetItem *pDNoItem = findNOItemByIP(sAddr); + QString strNo = pDNoItem->data(0,NO_ROLE).value(); + + if(!m_mapAddrToFiles.contains(sAddr)) + { + QVector vecData; + m_mapAddrToFiles[sAddr] = vecData; + } + + QJsonObject objec = msg.value(); + if(objec.contains("cmd")) + { + QJsonValue arrays_value = objec.take("cmd"); + //qDebug()<<"cmd ="< vecData = m_mapAddrToFiles.value(sAddr); + vecData.push_back(stData); + m_mapAddrToFiles[sAddr] = vecData; + //qDebug()<<"Addr::"< vecData; +// m_mapAddrToFiles[sAddr] = vecData; +// } + //QTreeWidgetItem *pNameItem = findNameItemByIP(sAddr); + + QTreeWidgetItem *pNOItem = findNOItemByIP(sAddr); + + QJsonObject objec = msg.value(); + if(objec.contains("cmd")) + { + QJsonValue arrays_value = objec.take("cmd"); + //qDebug()<<"cmd ="<parent()->text(0) + ")"; + } + else{ + //pNOItem->parent()->setText(0,str); + str = dataWatchName + " (" + pNOItem->parent()->text(0) + ")"; + } + pNOItem->parent()->setText(0,str);*/ + } + } + if(SystemInfoObj.contains("dataWatchNo")) + { + QJsonValue Json_value = SystemInfoObj.take("dataWatchNo"); + //qDebug()<<"dataWatchNo ="<text(0) + ": " + Json_value.toString(); + //pNOItem->setText(0,str); + pNOItem->setData(0, NO_ROLE, Json_value.toString()); + } + } + } + if(SystemInfoObj.contains("deviceType")) + { + + QJsonValue Json_value = SystemInfoObj.take("deviceType"); + // qDebug()<<"deviceType ="<child(i); + QString strFlag = pItem->data(0, FLAG_ROLE).value(); + + if("change" == strFlag) + { + pChangeItem = pItem; + } + else if ("size" == strFlag) + { + pSizeItem = pItem; + } + else if ("time" == strFlag) + { + pTimeItem = pItem; + } + else if ("manu" == strFlag) + { + pManulItem = pItem; + + } + } + + QTreeWidgetItem *pNewItem = new QTreeWidgetItem(); + pNewItem->setCheckState(0, Qt::Unchecked); + pNewItem->setText(0, sfileName); + pNewItem->setData(0, FLAG_ROLE, "file"); + QDateTime datetime = QDateTime::fromSecsSinceEpoch(iTime); + QString sTime = datetime.toString("yyyy/MM/dd hh:mm"); + pNewItem->setText(1, sTime); + + if(sfileName.contains("NONE")) + { + pNewItem->setText(2, QStringLiteral("正常")); + } + else if(sfileName.contains("ALARM")) + { + pNewItem->setText(2, QStringLiteral("警告")); + } + else if(sfileName.contains("DANGER")) + { + pNewItem->setText(2, QStringLiteral("危险")); + } + + //分类 + if(sfileName.contains("MANUAL")) + { + + datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNo + "\\" + "manu" + "\\"; + filename = datpath + sfileName; + QFileInfo file(filename); + if(file.exists()){ + + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,0); + pManulItem->addChild(pNewItem); + }else{ + QIcon icon(":/images/images/imgTreeIcon/remove2.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,0); + pManulItem->addChild(pNewItem); + } + + } + else if (sfileName.contains("TIME_INTERVAL") || sfileName.contains("TIME_OF_DAY") || sfileName.contains("MinIO")) + { + datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNo + "\\" + "time" + "\\"; + filename = datpath + sfileName; + QFileInfo file(filename); + if(file.exists()){ + + }else{ + QIcon icon(":/images/images/imgTreeIcon/remove2.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,0); + pTimeItem->addChild(pNewItem); + } + + } + else if (sfileName.contains("DELTA_EU") || sfileName.contains("DELTA_SPPEED")) + { + datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNo + "\\" + "change" + "\\"; + filename = datpath + sfileName; + QFileInfo file(filename); + if(file.exists()){ + + }else{ + QIcon icon(":/images/images/imgTreeIcon/remove2.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,0); + pChangeItem->addChild(pNewItem); + } + + } + else if (sfileName.contains("LEVEL-ALARM")|| sfileName.contains("LEVEL-DANGER")) + { + datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNo + "\\" + "size" + "\\"; + filename = datpath + sfileName; + QFileInfo file(filename); + if(file.exists()){ + pSizeItem->addChild(pNewItem); + }else{ + QIcon icon(":/images/images/imgTreeIcon/remove2.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,0); + pSizeItem->addChild(pNewItem); + } + } +} + +void MainWidget::TabBarCloseSlot() +{ + QPushButton *pBtn = dynamic_cast(QObject::sender()); + if(!pBtn) return; + + ChildForm *pForm = m_mapTabBtnToForm.value(pBtn); + if(!pForm) return; + + m_mapTabBtnToForm.remove(pBtn); + if(m_vecChildForm.contains(pForm)) m_vecChildForm.remove(m_vecChildForm.indexOf(pForm)); + if(m_mapChildFormToChannelID.contains(pForm)) m_mapChildFormToChannelID.remove(pForm); + + ui->tabWidget->removeTab( ui->tabWidget->indexOf(pForm)); +} +void MainWidget::PlayBtnSlot() +{ + if(!m_pTimer) return; + { + m_pTimer->stop(); + ui->PauseBtn->setToolTip(tr("暂停")); + } + +} +void MainWidget::TimerSlot() +{ + if(m_iCurCount == m_iCount || m_iCurCount == m_iRealCount) + { + m_iCurCount = m_iCount; + ui->horizontalSlider->setValue(m_iCurCount); + m_pTimer->stop(); + return; + } + ui->horizontalSlider->setValue(m_iCurCount); + if(m_backPlay) + m_iCurCount --; + else + m_iCurCount ++; +} +void MainWidget::Back1SBtnSlot() +{ + m_backPlay = true; + m_iCurCount -= 1; + if(m_iCurCount >= m_iRealCount) + m_iCurCount = m_iRealCount; + if(m_iCurCount < 0) + { + m_iCurCount = 0; + } + m_pTimer->start(1000); + ui->horizontalSlider->setValue(m_iCurCount); +} + +void MainWidget::Back2SBtnSlot() +{ + m_iCurCount -= 1; + if(m_iCurCount >= m_iRealCount) + m_iCurCount = m_iRealCount; + if(m_iCurCount < 0) + { + m_iCurCount = 0; + } + m_pTimer->stop(); + ui->horizontalSlider->setValue(m_iCurCount); +} + +void MainWidget::Back3SBtnSlot() +{ + m_iCurCount = 0; + m_pTimer->stop(); + ui->horizontalSlider->setValue(m_iCurCount); +} + +void MainWidget::Add1SBtnSlot() +{ + m_backPlay = false; + if(m_iCurCount > m_iCount) + { + m_iCurCount = m_iCount; + + } + if(m_iCurCount > m_iRealCount) + m_iCurCount = m_iRealCount; + m_pTimer->start(1000); + ui->horizontalSlider->setValue(m_iCurCount); +} + +void MainWidget::Add2SBtnSlot() +{ + m_iCurCount += 1; + if(m_iCurCount > m_iCount) + { + m_iCurCount = m_iCount; + } + if(m_iCurCount > m_iRealCount) + m_iCurCount = m_iRealCount; + m_pTimer->stop(); + ui->horizontalSlider->setValue(m_iCurCount); +} + +void MainWidget::Add3SBtnSlot() +{ + if(m_iRealCount < m_iCount) + m_iCurCount = m_iRealCount; + else + m_iCurCount = m_iCount; + m_pTimer->stop(); + ui->horizontalSlider->setValue(m_iCurCount); +} +void MainWidget::AddDevice() +{ + pAddDevice = new AddDeviceForm(this); //将类指针实例化 + connect(pAddDevice, SIGNAL(AddDeviceIP(QString,bool)), this, SLOT(SearchSlot(QString,bool))); + connect(pAddDevice, SIGNAL(AutoSearchIP()), this, SLOT(SearchSlot())); + pAddDevice->setWindowModality(Qt::ApplicationModal); + pAddDevice->show(); +} +void MainWidget::Report() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + if(m_mapChildFormToChannelID.size() > 3){ + MyMsgBox(QMessageBox::Warning,"警告","最大支持三张图谱导出报告!"); + return; + } + pReport = new ReportForm(this); //将类指针实例化 + pReport->setWindowModality(Qt::ApplicationModal); + connect(pReport, SIGNAL(ReportPDF(QStringList,QString)), this, SLOT(OutPDF(QStringList,QString))); + QDateTime current_date_time = QDateTime::currentDateTime(); + QString current_date = current_date_time.toString("yyyy-MM-dd"); + QString ReportFile = QCoreApplication::applicationDirPath() + "\\report\\" + m_sEquipNo + "_" + current_date + ".pdf"; + QDateTime time = QDateTime::fromTime_t(m_strCollectTime.toUInt()); + REPORT_INFO reportInfo; + QStringList strImagePathList; + QMap>::const_iterator mapIt = m_mapChildFormToChannelID.begin(); + for (; mapIt != m_mapChildFormToChannelID.end(); ++mapIt) + { + ChildForm *pChild = mapIt.key(); + QString strImagePath = ""; + QPixmap pixmap = pChild->GetSerise(strImagePath); + strImagePathList.push_back(strImagePath); + qDebug() << strImagePath<< endl; + } + reportInfo.DeviceMac = m_sEquipNo; + reportInfo.DevicemCollectTime = time.toString("yyyy-MM-dd hh:mm:ss"); + pReport->InitReport(ReportFile,strImagePathList,m_sEquipNo + "_" + current_date + ".pdf",reportInfo); + pReport->show(); +} +void MainWidget::InitData() +{ + setWindowTitle("Chaos Data Player"); + m_iCurCount = 0; + m_iCount = 0; + ui->horizontalSlider->setValue(0); + QString strCount = QString("%1/%2").arg(m_iCurCount).arg(m_iCount); + ui->label_value->setText(strCount); + ui->tabWidget->clear(); + m_vecGroupdata.clear(); + m_vecWaveInfo.clear(); + QVector().swap(m_vecGroupdata); + QVector().swap(m_vecWaveInfo); + QVector().swap(m_vecAllData); + QMap>::Iterator iter1 = mapWaveData.begin(); + for(iter1 = mapWaveData.begin();iter1 != mapWaveData.end();iter1++){ + QVector().swap(iter1.value()); + mapWaveData.erase(iter1); + } + QMap>::Iterator iter2 = m_mapChildFormToChannelID.begin(); + for(;iter2 != m_mapChildFormToChannelID.end();iter2++){ + QVector().swap(iter2.value()); + m_mapChildFormToChannelID.erase(iter2); + } + ui->horizontalSlider->setRange(0,0); + m_pTimer->stop(); +} +void MainWidget::ExitFile() +{ + if(mapWaveData.size() < 1) + return; + QMessageBox::StandardButton Msg = MyMsgBox(QMessageBox::Question,"提示","是否退出当前Dat文件",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes); + + if(Msg == QMessageBox::No) + return; + InitData(); + EnableGraph(true); +} +void MainWidget::Setting() +{ + pSetting = new SettingForm(this); + pSetting->show(); +} +void MainWidget::HideDev() +{ + QList m_splitterLengths(ui->splitter->sizes()); + if(!m_HideDevList){ + m_HideDevList = true; + m_splitterLengths[0] = 0; + ui->splitter->setSizes(m_splitterLengths); + }else{ + m_HideDevList = false; + m_splitterLengths[0] = 200; + m_splitterLengths[1] = 500; + ui->splitter->setSizes(m_splitterLengths); + } +} +void MainWidget::OutPDF(QStringList strResult,QString filePath) +{ + + QFile pdfFile(filePath); + qDebug() << filePath<setPageSize(QPagedPaintDevice::A4); // 设置纸张为A4 + pdfWriter->setResolution(300); // 设置纸张的分辨率为300,因此其像素为3508X2479 + int iMargin = 60; // 页边距 + pdfWriter->setPageMargins(QMarginsF(iMargin, iMargin, iMargin, iMargin)); + + QPainter* pPdfPainter = new QPainter(pdfWriter); // qt绘制工具 + // 标题,居中 + QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter); + option.setWrapMode(QTextOption::WordWrap); + + //字体 + QFont font; + font.setFamily(QString::fromLocal8Bit("宋体")); + //标题,字号 + int fontSize = 22; + font.setPointSize(fontSize); + pPdfPainter->setFont(font); // 为绘制工具设置字体 + pPdfPainter->drawText(QRect(0, 0, 1980, 100),Qt::AlignHCenter|Qt::AlignBottom, "故障分析诊断报告"); + /* int w = 200, h = 200; + QPixmap watermask = CreateWatermarkBg(w,h, QString("chaos")); + float imgDisScale = 1.0; + pPdfPainter->drawPixmap(QRect(0, 0, 500,300), watermask);*/ + + // 标题下边留白 + int iTop = 350; + // 左侧缩进 + int iLeft = 20; + pPdfPainter->drawRect(iLeft, iTop, 1980, 2750);//表格矩形方框 + pPdfPainter->drawLine(iLeft,iTop+100,iLeft+1980,iTop+100); + pPdfPainter->drawLine(iLeft,iTop+800,iLeft+1980,iTop+800); + //pPdfPainter->drawLine(iLeft,iTop+1000,iLeft+1980,iTop+1000); + //pPdfPainter->drawLine(300,iTop,300,iTop+2750); + /******************************************************以下为自定义绘图**************************************/ + + QPixmap pixmap(":/images/images/logo.png"); + pixmap = pixmap.scaled(200, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation); // 按比例缩放 + pPdfPainter->drawPixmap(1800,10,pixmap); + pPdfPainter->setFont(QFont("", 10)); + pPdfPainter->drawText(20,250,"终端名称:Data Watch"); + pPdfPainter->drawText(500,250,"终端MAC:"); + pPdfPainter->drawText(700,250,m_sEquipNo); + //pPdfPainter->drawText(1000,180,"采集通道:"); + //pPdfPainter->drawText(20,250,"通道名称:"); + //pPdfPainter->drawText(500,250,"测点名称:"); + pPdfPainter->drawText(1000,250,"采集时间:"); + QDateTime time = QDateTime::fromTime_t(m_strCollectTime.toUInt()); + pPdfPainter->drawText(1200,250,time.toString("yyyy-MM-dd hh:mm:ss")); + //pPdfPainter->drawText(iLeft+50,iTop+60,"诊断项目"); + pPdfPainter->drawText(iLeft+900,iTop+60,"诊断结果"); + pPdfPainter->drawText(iLeft+50,iTop+850,"诊断结果及建议:"); + for(int i = 0; i < strResult.size();i++){ + + pPdfPainter->drawText(iLeft+50,iTop+915 + i * 70,strResult[i]); + } + QString ReportTime = QStringLiteral("报告时间:%1").arg(current_date); + + pPdfPainter->drawText(20,320,ReportTime); + + QMap>::const_iterator mapIt = m_mapChildFormToChannelID.begin(); + for (int i = 0; mapIt != m_mapChildFormToChannelID.end(); ++mapIt,i++) + { + + ChildForm *pChild = mapIt.key(); + switch(pChild->m_iFormType){ + case FormType::TrendChartPlot: + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"趋势图"); + pPdfPainter->setPen(QColor(0,255,0)); + //pPdfPainter->drawLine(iLeft+290 + i * 610,iTop+650,iLeft+350 + i * 610,iTop+650); + break; + case FormType::TimeDomainPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"时域图"); + break; + case FormType::FrequencyDomainPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"频谱图"); + break; + case FormType::EnvChartPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"包络图"); + break; + case FormType::OrbitPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"轴心轨迹图"); + break; + case FormType::WaterFallPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"瀑布图"); + break; + case FormType::PolarPlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"极坐标图"); + break; + case FormType::ShaftCenterline: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"轴心位置图"); + break; + case FormType::BodePlot: + pPdfPainter->setPen(QColor(0,0,0)); + pPdfPainter->drawText(iLeft+290 + i * 610,iTop+600,"伯德图"); + break; + default: + break; + } + QString strImagePath = ""; + QPixmap pixmap = pChild->GetSerise(strImagePath); + pPdfPainter->drawPixmap(iLeft+80 + i * 610,iTop+120,pixmap); + + } +// QPixmap pixmap=QWidget::grab(QRect(ui->widget->x(),ui->widget->y(),ui->widget->frameGeometry().width(),ui->widget->frameGeometry().height())); + + delete pPdfPainter; + pdfFile.close(); + QDesktopServices::openUrl(QUrl::fromLocalFile(filePath)); + +} +QPixmap MainWidget::CreateWatermarkBg(uint16_t w, uint16_t h, QString content) +{ + QPixmap pm(w,h);//一张新空图 + pm.fill(Qt::transparent);//用透明色填充 + + QPainter painter(&pm); + int fontSize = 25/*25*/, spacing = 5; + QFont font("Ubuntu", fontSize, QFont::Thin); + font.setLetterSpacing(QFont::AbsoluteSpacing, spacing); + painter.setFont(font); + painter.setPen(QColor(200, 200, 200)); + painter.translate(pm.width() / 2, -pm.width() / 2);//调整位置 + + QFontMetricsF fontMetrics(font); + qreal font_w = fontMetrics.width(content); + qreal font_h = fontMetrics.height(); + + qreal ang = 45.0; + painter.rotate(ang); + int project_Y = pm.width() * sin(ang) + pm.height() * sin(ang);//原图像Y坐标在新坐标系Y轴上的投影长度。 + int project_X = pm.height()*sin(ang) + pm.width()*cos(ang);//原图像x坐标在新坐标系x轴上的投影长度。 + + int x_step = 1.5*font_w + 3*spacing; //在新坐标系X轴上的间距 + int y_step = (3*font_h); + int rowCnt = project_Y / y_step + 1; //在新坐标系下写多少行 + int colCnt = project_X / x_step; //在新坐标系下写多少列 + + for (int r = 0; r < rowCnt; r++)//在新坐标系下写多少行 + { + for (int c = 0; c < colCnt + 1; c++)//在新坐标系下写多少列 + { + painter.drawText(x_step * c, y_step * r,content); + } + } + return pm; +} + + +void MainWidget::SlidervalueChangedSlot(int value) +{ + m_iCurCount = value; + QString strCount = QString("%1/%2").arg(m_iCurCount).arg(m_iCount); + ui->label_value->setText(strCount); + QMap>::const_iterator mapIt = m_mapChildFormToChannelID.begin(); + for (; mapIt != m_mapChildFormToChannelID.end(); ++mapIt) + { + ChildForm *pChild = mapIt.key(); + QVector vecChannel = mapIt.value(); + + if( pChild->GetFormType() == TimeDomainPlot + || pChild->GetFormType() == SpecChartPlot + || pChild->GetFormType() == OrbitPlot + || pChild->GetFormType() == WaterFallPlot + ) + {//频域图,时域图,包络图,频谱图, + + pChild->handlePlayWave((value-1)*1,1); + + }else if(pChild->GetFormType() == TrendChartPlot){ + + pChild->handlePlayWave((value-1)*1,5); + + }else if(pChild->GetFormType() == FrequencyDomainPlot || + pChild->GetFormType() == EnvChartPlot){ + + pChild->handlePlayWave((value-1)*1,1); + } + + } +} +void MainWidget::ItemCheckStateSlot(QString strID, bool bChecked) +{ + ChildForm *pChild = dynamic_cast(QObject::sender()); + if(!pChild) return; + + QVector vecChannel; + if(m_mapChildFormToChannelID.contains(pChild)) vecChannel = m_mapChildFormToChannelID.value(pChild); + + if(vecChannel.contains(strID)) + { + if(!bChecked) vecChannel.remove(vecChannel.indexOf(strID)); + } + else + { + if(bChecked) vecChannel.push_back(strID); + } + + m_mapChildFormToChannelID[pChild] = vecChannel; + + if(!bChecked) return; + + if(pChild->GetFormType() == FrequencyDomainPlot || pChild->GetFormType() == TimeDomainPlot + || pChild->GetFormType() == EnvChartPlot || pChild->GetFormType() == SpecChartPlot + || pChild->GetFormType() == TrendChartPlot || pChild->GetFormType() == WaterFallPlot) + {//频域图,时域图,包络图,频谱图 + QString strChannelID = strID; + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); ++iter) + { + if((iter.key() == strChannelID)) + { + // pChild->m_waveData = stData; + qDebug() << "m_vecPushData" << iter.value().size() << endl; + pChild->AddSeries(strChannelID, iter.value()); + } + } + + } + else if (pChild->GetFormType() == OrbitPlot) //轴心轨迹 + { + QString strChannelID = strID; + QMap>::Iterator iter = mapWaveData.begin(); + QVector waveData; + QString ChannelID = "",speedChannelID = ""; + for (; iter != mapWaveData.end(); ++iter) + { + if((iter.key() == strChannelID)) + { + waveData = iter.value(); + ChannelID = iter.value().at(0).pairChannelID; + speedChannelID = iter.value().at(0).speedRefChannelId; + QString strChannelType = iter.value().at(0).sensorType; + if(strChannelType != "PROXIMETER") + return; + qDebug() << "speedChannelID" << speedChannelID << endl; + qDebug() << "ChannelID" << ChannelID << endl; + qDebug() << "size" << mapWaveData[ChannelID].size() << endl; + if(speedChannelID == "NONE" || speedChannelID == ""){ + MyMsgBox(QMessageBox::Warning,"警告","当前文件中没有转速通道数据"); + return; + } + pChild->AddOrbitSeries(strChannelID, mapWaveData[ChannelID],iter.value(),mapWaveData[speedChannelID]); + + } + /*if((iter.key() == strChannelID)) + { + waveData = iter.value(); + ChannelID = iter.value().at(0).pairChannelID; + speedChannelID = iter.value().at(0).SpeedProfileSpeed; + }else{ + if(ChannelID == iter.key()){ + pChild->AddOrbitSeries(strChannelID, waveData,iter.value()); + break; + } + }*/ + } + }else if(pChild->GetFormType() == BodePlot){ + QString strChannelID = strID; + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); ++iter){ + if((iter.key() == strChannelID)){ + + pChild->mapBodeData.insert(strID,iter.value()); + if(pChild->mapBodeData.size() < 2){ + QString ChannelID = iter.value().at(0).speedRefChannelId; + if(ChannelID == "NONE" || ChannelID == ""){ + MyMsgBox(QMessageBox::Warning,"警告","当前文件中没有绑定转速通道,请手动选择另一个通道"); + //return; + }else{ + pChild->mapBodeData.insert(strID,mapWaveData[ChannelID]); + pChild->AddBodeSeries(strChannelID, iter.value(),mapWaveData[ChannelID]); + return; + } + }else{ + QVector waveSpeedData; //转速 + QVector waveVibrateData; //加速度 + QMap>::Iterator iter = pChild->mapBodeData.begin(); + for (;iter != pChild->mapBodeData.end() ; iter++) { + if(iter.value()[0].sensorType != "ACCELEROMETER" && iter.value()[0].sensorType != "TACHOMETER"){ + MyMsgBox(QMessageBox::Warning,"警告","请选择转速和振动通道进行伯德图分析"); + return; + } + if(iter.value()[0].sensorType == "TACHOMETER"){ + waveSpeedData = iter.value(); + } + if(iter.value()[0].sensorType == "ACCELEROMETER"){//ACCELEROMETER + waveVibrateData = iter.value(); + } + } + pChild->AddBodeSeries(strChannelID, waveVibrateData,waveSpeedData); + } + } + } + }else if(pChild->GetFormType() == ShaftCenterline){//2个位移 + QString strChannelID = strID; + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); ++iter){ + if((iter.key() == strChannelID)){ + QString ChannelID = iter.value().at(0).pairChannelID; + QString ChannelType = iter.value().at(0).sensorType; + if((ChannelType != "PROXIMETER") && (ChannelID == "NONE" || ChannelID == "")){ + MyMsgBox(QMessageBox::Warning,"警告","请选择径向位移通道"); + return; + } + pChild->AddShaftCenterlineSeries(strChannelID, iter.value(),mapWaveData[ChannelID]); + } + } + }else if(pChild->GetFormType() == PolarPlot){ + QString strChannelID = strID; + QMap>::Iterator iter = mapWaveData.begin(); + QVector waveData; + QString speedChannelID = ""; + for (; iter != mapWaveData.end(); ++iter){ + if((iter.key() == strChannelID)){ + speedChannelID = iter.value().at(0).speedRefChannelId; + qDebug() << "speedChannelID"<AddPolarPlotSeries(strChannelID, mapWaveData[strChannelID],mapWaveData[speedChannelID]); + } + } + } +} +void MainWidget::OutSlot() +{ + ChildForm *pChild = dynamic_cast(QObject::sender()); + if(!pChild) return; + + int index = ui->tabWidget->indexOf(pChild); + if(index == -1) return; + ui->tabWidget->removeTab(index); + + pChild->setParent(this); + pChild->setWindowFlag(Qt::Window); + pChild->show(); + pChild->setTopWgtHiddent(false); + +} + +void MainWidget::ReturnSlot() +{ + ChildForm *pChild = dynamic_cast(QObject::sender()); + if(!pChild) return; + + int index = ui->tabWidget->indexOf(pChild); + if(index > -1) return; + + pChild->setTopWgtHiddent(true); + QIcon icon(""); + + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + ui->tabWidget->setCurrentWidget(pChild); +} + +void MainWidget::TrendChartPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::TrendChartPlot,tr("趋势图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("趋势图")); + pChild->SetFormType(FormType::TrendChartPlot); + + QIcon icon(":/images/images/imgDatamodel/M1.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} + +void MainWidget::TimeDomainPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::TimeDomainPlot,tr("时域图"),&m_DeviceInfo,this); + + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("时域图")); + pChild->SetFormType(FormType::TimeDomainPlot); + + QIcon icon(":/images/images/imgDatamodel/M2.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + connect(pChild, SIGNAL(PlayWaveSig()), this, SLOT(Add2SBtnSlot())); + connect(pChild, SIGNAL(InitWaveSig()), this, SLOT(Back3SBtnSlot())); +// connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::FrequencyDomainPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::FrequencyDomainPlot,tr("频域图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("频域图")); + pChild->SetFormType(FormType::FrequencyDomainPlot); + + QIcon icon(":/images/images/imgDatamodel/M9.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::EnvelopeAnalysisPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::EnvChartPlot,tr("包络图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("包络图")); + pChild->SetFormType(FormType::EnvChartPlot); + + QIcon icon(":/images/images/imgDatamodel/M10.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::WaterFallPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::WaterFallPlot,tr("瀑布图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("瀑布图")); + pChild->SetFormType(FormType::WaterFallPlot); + + QIcon icon(":/images/images/imgDatamodel/M4.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + // Child3DFrom *pChild3d = new Child3DFrom(this); + // pChild3d->setCloseBtnVisible(false); + // pChild3d->hideTopWgt(); +//// pChild->SetName(tr("包络图")); +//// pChild->SetFormType(FormType::EnvChartPlot); + +// QIcon icon(":/images/images/imgDatamodel/M4.png"); +// ui->tabWidget->addTab(pChild, icon, "瀑布图"); + ui->tabWidget->setCurrentWidget(pChild); + +} +void MainWidget::BodePlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::BodePlot,tr("Bode"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("伯德图")); + pChild->SetFormType(FormType::BodePlot); + QIcon icon(":/images/images/imgDatamodel/M5.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); + +} +void MainWidget::OrbitPlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::OrbitPlot,tr("轴心轨迹图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("轴心轨迹图")); + pChild->SetFormType(FormType::OrbitPlot); + + QIcon icon(":/images/images/imgDatamodel/M7.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::ShaftCenterlinePlotSlot() +{ + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Warning,"警告","请先打开数据文件!"); + return; + } + ChildForm *pChild = new ChildForm(FormType::ShaftCenterline,tr("轴心位置图"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("轴心位置图")); + pChild->SetFormType(FormType::ShaftCenterline); + + QIcon icon(":/images/images/imgDatamodel/M6.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size()>8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::PolarplotSlot() +{ + ChildForm *pChild = new ChildForm(FormType::PolarPlot,tr("极坐标"),&m_DeviceInfo,this); + pChild->setCloseBtnVisible(true); + pChild->hideTopWgt(); + pChild->SetName(tr("极坐标")); + pChild->SetFormType(FormType::PolarPlot); + + QIcon icon(":/images/images/imgDatamodel/M8.png"); + ui->tabWidget->addTab(pChild, icon, pChild->GetName()); + //pChild->AddPolarPlotSeries(); + QPushButton *pCustomButton = new QPushButton(); + pCustomButton->setFixedSize(14, 14); + pCustomButton->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/tabclose.png) 5; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/tabclose-h.png) 5; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/tabclose-p.png) 5; }"); + ((QTabBar*)(ui->tabWidget->tabBar()))->setTabButton(ui->tabWidget->indexOf(pChild),QTabBar::RightSide,pCustomButton); + connect(pCustomButton, SIGNAL(clicked()), this, SLOT(TabBarCloseSlot())); + m_mapTabBtnToForm[pCustomButton] = pChild; + + connect(pChild, SIGNAL(OutSig()), this, SLOT(OutSlot())); + connect(pChild, SIGNAL(ReturnSig()), this, SLOT(ReturnSlot())); + connect(pChild, SIGNAL(ItemCheckStateSignal(QString, bool)), this, SLOT(ItemCheckStateSlot(QString, bool))); + // connect(pChild, &ChildForm::sigRealTimeData, this, &MainWidget::slotRealTimeData); + + m_vecChildForm.push_back(pChild); + + QStringList strIDList,strChannleType,strChannleNameList; +// QVector::Iterator iter = m_vecPushData.begin(); + QMap>::Iterator iter = mapWaveData.begin(); + for (; iter != mapWaveData.end(); iter ++) + { + if(!strIDList.contains(iter.key())) + strIDList.push_back(iter.key()); + strChannleType.push_back(iter.value()[0].sensorType); + strChannleNameList.push_back(iter.value()[0].channelName); + } + if(mapWaveData.size() > 8) + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + else + pChild->SetDataIDs(strIDList, tr("Data Watch "),strChannleType,strChannleNameList); + + ui->tabWidget->setCurrentWidget(pChild); +} +void MainWidget::View3D() +{ +/* Child3DFrom *pChild = new Child3DFrom(this); + + QIcon icon(":/images/images/imgDatamodel/M7.png"); + ui->tabWidget->addTab(pChild, icon, "");*/ +} +void MainWidget::Dat2Csv() +{ + QString dirpath = QFileDialog::getExistingDirectory(this, QStringLiteral("选择目录"), "./", QFileDialog::ShowDirsOnly); + + if(dirpath.isEmpty()) return; + if(mapWaveData.size() < 1){ + MyMsgBox(QMessageBox::Information,"提示","请先打开数据文件!"); + return; + } + QProgressDialog *progressDialog = new QProgressDialog(this); + //QFont font("ZYSong18030", 12); + //progressDialog->setFont(font); + progressDialog->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); + progressDialog->setWindowModality(Qt::WindowModal); + progressDialog->setWindowTitle(tr("Please Wait")); + progressDialog->setLabelText(tr("转换中...")); + progressDialog->setCancelButton(0); + progressDialog->show(); + + qDebug() <<"mapWaveData.size()" < vecWaveData; + QVector vecWaveData128; + QMap>::Iterator iter = mapWaveData.begin(); + QString dirName = dirpath + "\\" + m_sEquipNo + "\\"; + QDir dir(dirName); + qDebug()<< "CVS = " << dirName << endl; + if(!dir.exists()) + { + dir.mkpath(dirName); + } + int progress = 0; + progressDialog->setRange(0, mapWaveData.size()); + for (; iter != mapWaveData.end(); iter ++){ + progressDialog->setValue(progress); + if (progressDialog->wasCanceled()) + { + delete progressDialog; + return ; + } + QDateTime time = QDateTime::fromTime_t(m_strCollectTime.toUInt()); + QString DevicemCollectTime = time.toString("yyyy-MM-dd_hhmmss"); + QString filename = QString(dirName + "%1-%2-%3.csv").arg(iter.key()).arg(iter.value().at(0).sensorType).arg(DevicemCollectTime); + QFile file(filename); + qDebug()<< "filename = "<= iter.value().at(0).Time){ + QVector vecSpeed; + for (int k = 0 ; k < iter.value().at(i).waveData.size(); k++) { + vecSpeed.push_back(iter.value().at(i).waveData[k]); + // out << iter.value().at(i).waveData[k] << ","; + // out << "\n"; + } + qDebug() <<"vecSpeed" << vecSpeed.size() << endl; + float timeTemp = 0; + for (int i = 1; i < vecSpeed.size(); i++) { + timeTemp = (vecSpeed[i] - vecSpeed[i-1]) + timeTemp; + } + timeTemp = timeTemp / (vecSpeed.size() - 1); + float mSpeedProfileSpeed = (1 / timeTemp * 60) / (iter.value().at(i).iKeyCount); // 计算转速 + qDebug() <<"mSpeedProfileSpeed" <readAll().split("\n");//每行以\n区分 + qDebug() << "tempOption.count " << tempOption.count() << endl; + QStringList tempbar; + for(int i = 1 ; i < tempOption.count()-1 ; i++) + { + tempbar = tempOption.at(i).split(",");//一行中的单元格以,区分 + for(int j = 0; j < tempbar.size();j++) + { + m_vecCsvData[j].wavedata.push_back(tempbar.at(j).toFloat()); + m_vecCsvData[j].channelId = QString(j+1); + } + } + qDebug() << "tempbar " << m_vecCsvData[0].wavedata.at(0) << endl; + file.close();// +} +void MainWidget::ReadDatData(QString strPath,QString strFileName,QString strIP) +{ + ui->tabWidget->clear(); + + InitData(); + m_strIP = strIP; + m_strDatTime = strFileName.right(30); + m_strDatTime = m_strDatTime.left(26); + QString Tile = "Chaos Data Player @ " + strFileName; + setWindowTitle(Tile); + QFile file(strPath); + if (!file.open(QIODevice::ReadOnly)) + { + qDebug() << "::MainWidget::ReadDatData() cannot open file for read"; + return; + } + ///转无线传感器的dat文件 + /// +// QString strFilePath = strPath.replace(strFileName,""); +// QStringList fileList = getFileListUnderDir(strFilePath); +// foreach (auto DatFileName, fileList) +// { +// char Time[32]; +// QVector vecDat; +// QFile file2(strFilePath + DatFileName); +// qDebug() << strFilePath + DatFileName; +// if (!file2.open(QIODevice::ReadOnly)) +// { +// qDebug() << "::MainWidget::ReadDatData() cannot open file for read"; +// return; +// } +// file2.read((char*)Time, sizeof(Time)); +// while (!file2.atEnd()) { +// float f; +// file2.read((char *)&f, sizeof(f)); +// vecDat.push_back(f); +// } +// DatFileName.replace(".dat",".csv"); +// QString filename = "e:/CSV/" + DatFileName; +// QFile file1(filename); +// qDebug()<< "filename = "<setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint); + progressDialog->setWindowModality(Qt::WindowModal); + progressDialog->setWindowTitle(tr("Please Wait")); + progressDialog->setLabelText(tr("读取中...")); + progressDialog->setCancelButton(0); + progressDialog->show(); + + + QTime startTime = QTime::currentTime(); +// qDebug() << "Vector 的 容量为1" << m_vecPushData.capacity() << endl; + qDebug() << "m_vecAllData 的 容量为2" << m_vecAllData.capacity() << endl; + m_vecGroupdata.clear(); + m_vecWaveInfo.clear(); + QVector().swap(m_vecGroupdata); + QVector().swap(m_vecWaveInfo); + QVector().swap(m_vecAllData); + QMap>::Iterator iter1 = mapWaveData.begin(); + for(iter1 = mapWaveData.begin();iter1 !=mapWaveData.end();iter1++){ + QVector().swap(iter1.value()); + mapWaveData.erase(iter1); + } + QMap>::Iterator iter2 = m_mapChildFormToChannelID.begin(); + for(;iter2 != m_mapChildFormToChannelID.end();iter2++){ + QVector().swap(iter2.value()); + m_mapChildFormToChannelID.erase(iter2); + } +// qDebug() << "Vector 的 容量为2" << m_vecPushData.capacity() << endl; + qDebug() << "m_vecAllData 的 容量为2" << m_vecAllData.capacity() << endl; +// m_vecPushData.clear(); + int theSize = 0; //通道数 + //读12字节头文件 + int iJsonSize, iChannelsize; + char equipNo[12]; //设备No 12字节 + char time[10]; //数据起始时间 10字节 + + file.read((char*)&iChannelsize, sizeof(iChannelsize)); + + qDebug() << "::MainWidget::ReadDatData() Channelsize:" << iChannelsize; + int iCount; //存储dat文件原始数据秒数 + file.read((char*)&iCount, sizeof(iCount)); + qDebug() << "::MainWidget::ReadDatData() iCount:" << iCount; + + file.read(equipNo, sizeof(equipNo)); + QString sEquipNo(equipNo); + m_sEquipNo = sEquipNo.left(12); + qDebug() << "::MainWidget::ReadDatData() equipNo:" << m_sEquipNo; + file.read(time, sizeof(time)); + QString CollectTime(time); + m_strCollectTime = CollectTime.left(10); + qDebug() << "::MainWidget::ReadDatData() time:" << m_strCollectTime; + file.read((char *)&iJsonSize, sizeof(iJsonSize)); + qDebug() << "::MainWidget::ReadDatData() iJsonSize:" << iJsonSize; + + //读json串 + char *buf0 = (char *)malloc(sizeof(char) *iJsonSize); + file.read(buf0,iJsonSize); + /*QString filename1 = QString("e://json.txt"); + QFile file1(filename1); + qDebug()<< "filename = "< pData; + int j = 0; + int temCount = 0; + int flag = -1; + progressDialog->setRange(0, iCount * channels-1); + + while (!file.atEnd()) { + file.read((char *)&Count, sizeof(Count)); + //qDebug()<<"Count" << Count << "temCount" < temCount && flag == 0)//过滤超出的秒数的数据 + break; + if(Count == temCount && flag == 0) + flag = 1; + if(Count < temCount || flag == 1){//过滤原始数据中转速多余数据 + file.read(buf, sizeof(buf)); + file.read((char *)&waveSize, sizeof(waveSize)); + float f = 0.0; + QVector vecSpeed; + qDebug()<<"waveSize" < 131072){ + qDebug() << "waveSize" << endl; + delete progressDialog; + file.close(); + MyMsgBox(QMessageBox::Warning,"警告","Dat文件不符合规范"); + return; + } + for (int i = 0; i < waveSize; i++) { + file.read((char *)&f, sizeof(f)); + m_WaveChnData[j].channelId = buf; + m_WaveChnData[j].waveData.push_back(f); + m_WaveChnData[j].Second = Count; + } + + temCount = Count; + qDebug()<<"::MainWidget::ReadDatData() wave.channelId" << m_WaveChnData[j].channelId<<" wave.count"<setValue(j); + if (progressDialog->wasCanceled()) + { + + delete progressDialog; + file.close(); + return ; + } + j++; + } + + /*if(temCount != iCount){ + MyMsgBox(QMessageBox::Warning,"警告","Dat文件采集秒数与实际读取秒数不一致"); + iCount = temCount; + }*/ + + qDebug()<::iterator iter = m_vecWaveInfo.begin(); + int linecolor = 0; + + for (;iter != m_vecWaveInfo.end() ; iter++ ) { + QVector m_vecPushData1; + WAVE_DATA wave; + int ii = 0; + for(int i = 0; i < j; i++){ + + if(iter->channelId.left(15) == m_WaveChnData[i].channelId.left(15)){ + wave.waveData = m_WaveChnData[i].waveData; + + float sum = 0.0; + if(iter->sensorType == "ACCELEROMETER" || iter->sensorType == "MICROPHONE" || + iter->sensorType == "PROXIMETER" || iter->sensorType == "VELOCITY" || + iter->sensorType == "TACHOMETER" || iter->sensorType == "THRUST" || + iter->sensorType == "FAST_VOLTAGE"){ + sum = std::accumulate(std::begin(wave.waveData), std::end(wave.waveData), 0.0); + float size = m_WaveChnData[i].waveData.size(); + wave.mean = sum/size; + + }else{ + sum = 0.0; + } + if(iter->sensorType == "TACHOMETER"){ + wave.TimeStamp = m_WaveChnData[i].TimeStamp; + qDebug()<< "iCount" <SpeedProfileSpeed; + wave.wavesize = wave.waveData.size(); + wave.SamleRate = iter->channelSamleRate; + wave.sensorType = iter->sensorType; + wave.channelId = iter->channelId; + wave.channelNo = theSize; + wave.Time = iCount; + wave.channelName = iter->channelName; + wave.pairChannelID = iter->pairChannelID; + wave.sensorEngineeringUnit = iter->sensorEngineeringUnit; + wave.speedRefChannelId = iter->speedRefChannelId; + wave.RMSValue = iter->RMSValue; + + wave.iTrigger = iter->iTrigger; + wave.iKeyCount = iter->iKeyCount; + wave.iTriggerValue = iter->iTriggerValue; + wave.iHysteresis = iter->iHysteresis; + wave.tachAutoTach = iter->tachAutoTach; + wave.sensorGapVoltage = iter->sensorGapVoltage; + wave.sensorSensitivity = iter->sensorSensitivity; + + switch(linecolor){ + case 0: + wave.linColor = Qt::green ; + break; + case 1: + wave.linColor = QColor(30,144,255) ; + break; + case 2: + wave.linColor = QColor(255,182,193) ; + break; + case 3: + wave.linColor = Qt::cyan ; + break; + case 4: + wave.linColor = Qt::magenta ; + break; + case 5: + wave.linColor = Qt::yellow ; + break; + case 6: + wave.linColor = QColor(255,69,0) ; + break; + case 7: + wave.linColor = QColor(0, 255, 127) ; + break; + case 8: + wave.linColor = QColor(255,140,0) ; + break; + case 9: + wave.linColor = QColor(0, 191, 255) ; + break; + case 10: + wave.linColor = Qt::darkMagenta ; + break; + case 11: + wave.linColor = Qt::lightGray ; + break; + case 12: + wave.linColor = Qt::darkYellow ; + break; + case 13: + wave.linColor = Qt::gray ; + break; + case 14: + wave.linColor = QColor(255, 218, 185) ; + break; + case 15: + wave.linColor = QColor(255, 20, 147) ; + break; + default: + break; + } + m_vecPushData1.push_back(wave); + //qDebug()<<"m_vecPushData1"<channelId,m_vecPushData1); + m_iRealCount = m_vecPushData1.size(); + //qDebug()<<"mapWaveData size"<horizontalSlider->setRange(1, m_iCount); + QString strCount = QString("%1/%2").arg(m_iCurCount).arg(m_iCount); + ui->label_value->setText(strCount); + + QTime stopTime = QTime::currentTime(); + qDebug() << "Time: " << startTime.msecsTo(stopTime) << "ms" < m_splitterLengths(ui->splitter->sizes()); + m_HideDevList = true; + m_splitterLengths[0] = 0; + ui->splitter->setSizes(m_splitterLengths); + + if(m_iRealCount < 1){ + MyMsgBox(QMessageBox::Warning,"警告","未读取到数据!"); + return; + } + + TrendChartPlotSlot(); + EnableGraph(); + + +} +void MainWidget::OpenFileSlot() +{ + //同时打开多个文件 + QSettings settings; + QStringList files = settings.value("recentFileList").toStringList();//读取recentFileList的值 + qDebug() << "file size" << files.size() << endl; + for(int i = 0; i < files.size();i++){ + qDebug() << files[i] << endl; + } + + QStringList pathList = QFileDialog::getOpenFileNames(this, tr("选择文件"), tr(""), tr("*.dat")); + foreach(QString strPath, pathList) + { + qDebug() << "::MainWidget::OpenFileSlot() path=" << strPath; + QFileInfo fileinfo; + fileinfo = QFileInfo(strPath); + QString file_suffix = fileinfo.suffix(); + QString FileName = fileinfo.fileName(); + if(file_suffix == "dat"){ + ReadDatData(strPath,FileName); + }else if(file_suffix == "csv"){ + ReadCsvData(strPath); + } + + } +} +void MainWidget::RetSlot(QString strjson,QString strip) +{ + QScriptEngine engine; + QScriptValue sc = engine.evaluate("value=" + strjson); + int cmdType = sc.property("cmd").toString().toInt(); + switch (cmdType) { + case 4:{ + + QString equipNo = sc.property("equipmentNo").toString(); + global::MacAddr_G = sc.property("dataWatchNo").toString(); + global::IpAddr_G = sc.property("localServerIpAddress").toString(); + qDebug() << "mac地址:" << global::MacAddr_G; + QString show = ""; + QString way = sc.property("way").toString(); + if (way.compare("udp") == 0) { + show = "校验成功"; + } else if (way.compare("mul") == 0) { + show = "MAC:" + global::MacAddr_G + "SERVERIP:" + global::IpAddr_G; + } + deviceInfo.DeviceMac = global::MacAddr_G; + deviceInfo.DeviceIP = strip; + int iRet = sql_db.OperateDeviceData(deviceInfo); + if(AddFlag){ + pAddDevice->UpdateDeviceInfo(); + if(iRet < 0){ + MyMsgBox(QMessageBox::Question,"警告","设备已经存在,请勿重复添加!"); + return ; + } + } + IpSlot(strip,global::MacAddr_G); + AddFlag = false; + + //ui->plainTextEdit->appendPlainText(show); + } + break; + default: + break; + } + //ui->Mac_comboBox->addItem(global::MacAddr_G); +} +QStringList MainWidget::getFileListUnderDir(const QString &dirPath) +{ + QStringList fileList; + QDir dir(dirPath); + QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Dirs); + foreach (auto fileInfo, fileInfoList) { + if(fileInfo.isDir()) + { + + getFileListUnderDir(fileInfo.absoluteFilePath()); + } + + if(fileInfo.isFile()) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << fileInfo.absoluteFilePath(); + fileList.append(fileInfo.fileName()); + } + } + return fileList; +} +void MainWidget::IpSlot(QString strip,QString strMAC,QString strName) +{ + + QTreeWidgetItem *pItem = findNOItemByIP(strip); + if(pItem != NULL){ + return ; + } + + //第一层树 + qDebug() << "strip:::::::" << strip; + /*QString strArg = "ping " + strip + " -n 1 -i 2"; + int exitcode = QProcess::execute(strArg); + qDebug() << "strip:::::::" << strip << exitcode;*/ + QTreeWidgetItem *pTopItem = new QTreeWidgetItem(); + + QIcon icon(":/images/images/imgTreeIcon/remove2.png"); + pTopItem->setIcon(0, icon); + + + QString str1 = ""; + if(strName == "") + str1 = "Data Watch (" + strip + ")"; + else + str1 = strName + " (" + strip + ")"; + + pTopItem->setText(0, str1); + pTopItem->setData(0, IP_ROLE, strip); + pTopItem->setData(0, FLAG_ROLE, "Data Watch"); + ui->treeWidget->addTopLevelItem(pTopItem); + + + + //第二层树 + QTreeWidgetItem *pConfigItem = new QTreeWidgetItem(pTopItem); + QIcon iconConfig(":/images/images/imgTreeIcon/config.png"); + pConfigItem->setIcon(0, iconConfig); + pConfigItem->setText(0, QStringLiteral("设备配置")); + pConfigItem->setData(0, FLAG_ROLE, "config"); + +// QTreeWidgetItem *pNameItem = new QTreeWidgetItem(pTopItem); +// QIcon iconName(":/images/images/imgTreeIcon/data.png"); +// pNameItem->setIcon(0, iconName); +// pNameItem->setText(0, QStringLiteral("设备名称")); +// pNameItem->setData(0, FLAG_ROLE, "name"); + + QTreeWidgetItem *pNOItem = new QTreeWidgetItem(pTopItem); + QIcon iconNO(":/images/images/imgTreeIcon/data.png"); + pNOItem->setIcon(0, iconNO); + pNOItem->setText(0, QStringLiteral("设备号")); + pNOItem->setData(0, FLAG_ROLE, "NO"); + pNOItem->setData(0, NO_ROLE, strMAC); + QString str = pNOItem->text(0) + ": " + strMAC; + pNOItem->setText(0, str); + + QTreeWidgetItem *pDataItem = new QTreeWidgetItem(pTopItem); + QIcon iconData(":/images/images/imgTreeIcon/data.png"); + pDataItem->setIcon(0, iconData); + pDataItem->setText(0, QStringLiteral("数据")); + pDataItem->setData(0, FLAG_ROLE, "data"); + + //第三层树 + QTreeWidgetItem *pChangeItem = new QTreeWidgetItem(pDataItem); + QIcon iconChange(":/images/images/imgTreeIcon/artic66.png"); + pChangeItem->setIcon(0, iconChange); + pChangeItem->setText(0, QStringLiteral("变化")); + pChangeItem->setData(0, FLAG_ROLE, "change"); + + QTreeWidgetItem *pSizeItem = new QTreeWidgetItem(pDataItem); + pSizeItem->setIcon(0, iconChange); + pSizeItem->setText(0, QStringLiteral("大小")); + pSizeItem->setData(0, FLAG_ROLE, "size"); + + QTreeWidgetItem *pTimeItem = new QTreeWidgetItem(pDataItem); + pTimeItem->setIcon(0, iconChange); + pTimeItem->setText(0, QStringLiteral("时间触发")); + pTimeItem->setData(0, FLAG_ROLE, "time"); + + QTreeWidgetItem *pManulItem = new QTreeWidgetItem(pDataItem); + pManulItem->setIcon(0, iconChange); + pManulItem->setText(0, QStringLiteral("手动触发")); + pManulItem->setData(0, FLAG_ROLE, "manu"); + + //扫描本地dat文件 + QString strDatPath = QCoreApplication::applicationDirPath() + "\\dat\\" + strMAC; + + qDebug() << __FUNCTION__ << __LINE__ << " : " << strDatPath; + QDir dir(strDatPath); + QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot | QDir::Dirs); + foreach (auto fileInfo, fileInfoList) { + if(fileInfo.isDir()) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << fileInfo.absoluteFilePath(); + //分类 + if(fileInfo.absoluteFilePath().contains("manu")) + { + QStringList fileList = getFileListUnderDir(fileInfo.absoluteFilePath()); + foreach (auto DatFileName, fileList) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << DatFileName; + QTreeWidgetItem *pNewItem = new QTreeWidgetItem(); + pNewItem->setCheckState(0, Qt::Unchecked); + pNewItem->setText(0, DatFileName); + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,1); + pManulItem->addChild(pNewItem); + } + // + //datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNo + "\\" + "manu" + "\\"; + + } + else if (fileInfo.absoluteFilePath().contains("time")) + { + QStringList fileList = getFileListUnderDir(fileInfo.absoluteFilePath()); + foreach (auto DatFileName, fileList) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << DatFileName; + QTreeWidgetItem *pNewItem = new QTreeWidgetItem(); + pNewItem->setCheckState(0, Qt::Unchecked); + pNewItem->setText(0, DatFileName); + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,1); + pTimeItem->addChild(pNewItem); + } + + } + else if (fileInfo.absoluteFilePath().contains("size")) + { + QStringList fileList = getFileListUnderDir(fileInfo.absoluteFilePath()); + foreach (auto DatFileName, fileList) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << DatFileName; + QTreeWidgetItem *pNewItem = new QTreeWidgetItem(); + pNewItem->setCheckState(0, Qt::Unchecked); + pNewItem->setText(0, DatFileName); + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,1); + pSizeItem->addChild(pNewItem); + } + + + } + else if (fileInfo.absoluteFilePath().contains("change")) + { + QStringList fileList = getFileListUnderDir(fileInfo.absoluteFilePath()); + foreach (auto DatFileName, fileList) + { + qDebug() << __FUNCTION__ << __LINE__ << " : " << DatFileName; + QTreeWidgetItem *pNewItem = new QTreeWidgetItem(); + pNewItem->setCheckState(0, Qt::Unchecked); + pNewItem->setText(0, DatFileName); + QIcon icon(":/images/images/imgTreeIcon/remove6.png"); + pNewItem->setIcon(0, icon); + pNewItem->setData(0,FILE_ROLE,1); + pChangeItem->addChild(pNewItem); + } + + } + } + } + + if(m_pNetMgr) + { + + m_pNetMgr->RequestFileInfo(strip); + m_pNetMgr->RequestChannelInfo(strip); + + } +} + +void MainWidget::slotCustomContextMenuRequested(const QPoint &pos) +{ + qDebug()<<"MainWidget::slotCustomContextMenuRequested"<treeWidget->itemAt(pos); + qDebug()<<"slotCustomContextMenuRequested"; + if(pItem == NULL) + return; + + if(pItem && pItem->parent() &&(pItem->parent()->data(0, FLAG_ROLE).value().contains("change") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("size") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("time") || + pItem->parent()->data(0, FLAG_ROLE).value().contains("manu")) + ) + { + QString strIP = pItem->parent()->parent()->parent()->data(0, IP_ROLE).value(); + QTreeWidgetItem *pItemNO = findNOItemByIP(strIP); + QString str = pItem->parent()->data(0, FLAG_ROLE).value(); + QString strNO = pItemNO->data(0,NO_ROLE).value(); + QString strData = pItem->parent()->data(0, FLAG_ROLE).value(); + QString FileName = pItem->text(0); + qDebug()<<"MainWidget"<data(0,FILE_ROLE).value() == "0"){//文件不在本地 + pActionOpen->setEnabled(false); + pActionDel->setEnabled(false); + } + if(pAction == menu.exec(QCursor::pos())) + { + qDebug()<<"doDownLoad"; + + QString datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNO + "\\" + strData + "\\"; + QFileInfo file(datpath + FileName); + if(file.exists()) + { + MyMsgBox(QMessageBox::Information,"提示","文件已存在!"); + return; + } + doDownLoad(pItem, datpath + FileName); + } + else if(pActionOpen == menu.exec(QCursor::pos())) + { + QString datpath = QCoreApplication::applicationDirPath() + "\\Dat\\" + strNO + "\\" + strData + "\\"; + qDebug()<<"MainWidget"<data(0, FLAG_ROLE).value().contains("Data Watch")){ + qDebug()<<"Data Watch"; + QMenu menu; + QAction *pAction = menu.addAction(QStringLiteral("删除")); + + if(pAction == menu.exec(QCursor::pos())){ + QString sAddr = pItem->text(0); + int bpos = sAddr.indexOf("("); + sAddr = sAddr.right(sAddr.length()- bpos -1); + sAddr = sAddr.left(sAddr.length()-1); + QString tablename = "t_Device",col = "DeviceIP"; + sql_db.DeleteData(tablename,col,sAddr); + ui->treeWidget->clear(); + InitDevList(); + } + + } + + +} + +void MainWidget::doDownLoad(QTreeWidgetItem *pItem, QString sPath) +{ + qDebug()<<"[MainWidget::doDownLoad]"; + //1、文件/2、“类型(比如:大小)”/3、“数据”/4、“IP” 节点 + QString str = pItem->parent()->data(0, FLAG_ROLE).value(); + qDebug() << str << endl; + if(pItem && pItem->parent() && pItem->parent()->parent()) + { + QTreeWidgetItem *pTopItem = pItem->parent()->parent(); + int iCount = pItem->parent()->childCount(); + for (int i = 0; i < iCount; ++i) + { + QTreeWidgetItem *pChildItem = pItem->parent()->child(i); + if(pChildItem->isSelected() && m_pNetMgr) + { + QString sAddr = pChildItem->text(0); + QString sIP = pTopItem->parent()->text(0); + int bpos = sIP.indexOf("("); + sIP = sIP.right(sIP.length()- bpos -1); + sIP = sIP.left(sIP.length()-1); + m_pNetMgr->RequestDownload(sIP, sAddr, sPath + "/" +sAddr); + qDebug()<setData(0,FILE_ROLE,1); + pItem->setIcon(0, icon); + } + //m_pNetMgr->RequestFileList(sIP); + } + + } + } + +} + +void MainWidget::EnableGraph(bool isOpen) +{ + if(isOpen){ + ui->modelBtn_TrendChart->setEnabled(false); + ui->modelBtn_TrendChart->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M1-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M1-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M1-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M1-p.png) 1; }"); + + ui->modelBtn_TimeDomain->setEnabled(false); + ui->modelBtn_TimeDomain->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M2-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M2-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M2-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M2-p.png) 1; }"); + + ui->modelBtn_spec->setEnabled(false); + ui->modelBtn_spec->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M9-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M9-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M9-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M9-p.png) 1; }"); + + ui->modelBtn_4->setEnabled(false); + ui->modelBtn_4->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M4-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M4-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M4-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M4-p.png) 1; }"); + + ui->modelBtn_5->setEnabled(false); + ui->modelBtn_5->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M5-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M5-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M5-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M5-p.png) 1; }"); + + ui->modelBtn_env->setEnabled(false); + ui->modelBtn_env->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M10-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M10-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M10-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M10-p.png) 1; }"); + + ui->modelBtn_6->setEnabled(false); + ui->modelBtn_6->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M6-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M6-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M6-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M6-p.png) 1; }"); + + ui->modelBtn_7->setEnabled(false); + ui->modelBtn_7->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M7-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M7-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M7-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M7-p.png) 1; }"); + + // ui->modelBtn_FrequencyDomain->setEnabled(true); + // ui->modelBtn_FrequencyDomain->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M3-p.png) 1; }\ + // QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M3-h.png) 1; }\ + // QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M3-p.png) 1; }\ + // QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M3-p.png) 1; }"); + + ui->modelBtn_8->setEnabled(false); + ui->modelBtn_8->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M8-p.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M8-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M8-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M8-p.png) 1; }"); + }else{ + ui->modelBtn_TrendChart->setEnabled(true); + ui->modelBtn_TrendChart->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M1.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M1-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M1-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M1-p.png) 1; }"); + + ui->modelBtn_TimeDomain->setEnabled(true); + ui->modelBtn_TimeDomain->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M2.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M2-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M2-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M2-p.png) 1; }"); + + ui->modelBtn_spec->setEnabled(true); + ui->modelBtn_spec->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M9.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M9-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M9-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M9-p.png) 1; }"); + + ui->modelBtn_4->setEnabled(true); + ui->modelBtn_4->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M4.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M4-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M4-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M4-p.png) 1; }"); + + ui->modelBtn_5->setEnabled(true); + ui->modelBtn_5->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M5.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M5-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M5-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M5-p.png) 1; }"); + + ui->modelBtn_env->setEnabled(true); + ui->modelBtn_env->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M10.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M10-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M10-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M10-p.png) 1; }"); + + ui->modelBtn_6->setEnabled(true); + ui->modelBtn_6->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M6.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M6-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M6-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M6-p.png) 1; }"); + + ui->modelBtn_7->setEnabled(true); + ui->modelBtn_7->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M7.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M7-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M7-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M7-p.png) 1; }"); + + // ui->modelBtn_FrequencyDomain->setEnabled(true); + // ui->modelBtn_FrequencyDomain->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M3.png) 1; }\ + // QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M3-h.png) 1; }\ + // QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M3-p.png) 1; }\ + // QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M3-p.png) 1; }"); + + ui->modelBtn_8->setEnabled(true); + ui->modelBtn_8->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M8.png) 1; }\ + QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M8-h.png) 1; }\ + QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M8-p.png) 1; }\ + QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M8-p.png) 1; }"); + } + +// ui->modelBtn_11->setEnabled(true); +// ui->modelBtn_11->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M11.png) 1; }\ +// QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M11-h.png) 1; }\ +// QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M11-p.png) 1; }\ +// QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M11-p.png) 1; }"); + +// ui->modelBtn_12->setEnabled(true); +// ui->modelBtn_12->setStyleSheet(" QPushButton { border-image:url(:/images/images/imgDatamodel/M12.png) 1; }\ +// QPushButton:hover { border-image:url(:/images/images/imgDatamodel/M12-h.png) 1; }\ +// QPushButton:pressed {border-image:url(:/images/images/imgDatamodel/M12-p.png) 1; }\ +// QPushButton:checked {border-image:url(:/images/images/imgDatamodel/M12-p.png) 1; }"); +} diff --git a/ChaosDataPlayer/MainWidget.h b/ChaosDataPlayer/MainWidget.h new file mode 100644 index 0000000..790cf47 --- /dev/null +++ b/ChaosDataPlayer/MainWidget.h @@ -0,0 +1,156 @@ +#ifndef MAINWIDGET_H +#define MAINWIDGET_H + +#include +#include + +#include "BaseWgt.h" +#include "global.h" +#include "DataParsing.h" +#include "sqlitedb.h" +#include "Adddeviceform.h" +#include "Reportform.h" +#include "SettingForm.h" + + +class ChildForm; +class CIDWUdp; +class NetMgr; +class QTreeWidgetItem; +class QMenu; +class SqliteDB; +class global; + +struct FileData +{ + QString sfileName; + int iCreatTime; + int iFileSize; + FileData() + { + iCreatTime = 0; + iFileSize = 0; + } +}; + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWidget; } +QT_END_NAMESPACE + +class MainWidget : public BaseWgt +{ + Q_OBJECT + +public: + MainWidget(QWidget *parent = nullptr); + ~MainWidget(); + SqliteDB sql_db; + void InitDevList(); +public slots: + void TrendChartPlotSlot(); + void TimeDomainPlotSlot(); + void FrequencyDomainPlotSlot(); + void EnvelopeAnalysisPlotSlot(); + void WaterFallPlotSlot(); + void OrbitPlotSlot(); + void PolarplotSlot(); + void BodePlotSlot(); + void ShaftCenterlinePlotSlot(); + void OutSlot(); + void ReturnSlot(); + void View3D(); + void Dat2Csv(); + //网络请求数据响应 + void slotNetMgr(QString sAddr,const QVariant& msg); + void slotItemDoubleClicked(QTreeWidgetItem *pItem, int column); +private slots: + void TabBarCloseSlot(); + void InitSignalandSlot(); + void ItemCheckStateSlot(QString strID, bool bChecked); + void OpenFileSlot(); + + void WebBtnSlot(QString sAddr = ""); + void RefreshBtnSlot(); + void SearchSlot(QString strIP = "",bool AutoSearch = true); + void SlidervalueChangedSlot(int value); + QPixmap CreateWatermarkBg(uint16_t w, uint16_t h, QString content); + //定时器槽函数 + void TimerSlot(); + + void PlayBtnSlot(); + void Back1SBtnSlot(); + void Back2SBtnSlot(); + void Back3SBtnSlot(); + void Add1SBtnSlot(); + void Add2SBtnSlot(); + void Add3SBtnSlot(); + void OutPDF(QStringList strResult,QString filePath); + void AddDevice(); + void HideDev(); + void Report(); + void ExitFile(); + void InitData(); + void Setting(); + //接收数据槽函数 + void RetSlot(QString strjson,QString strip); + void IpSlot(QString strip,QString strMAC = "",QString strName = ""); + + //tree widget 右击信号 + void slotCustomContextMenuRequested(const QPoint &pos); + +private: + + bool m_HideDevList; + void Init(); + void EnableGraph(bool isOpen = false); + +private: + void doDownLoad(QTreeWidgetItem *pItem, QString sPath); + //解析HTTP数据 1、文件列表 2、文件配置信息 + void parseFileListData(QString sAddr,const QVariant& msg); + void parseFileInfoData(QString sAddr,const QVariant& msg); + void paraseChannelInfo(QString aAddr,const QVariant& msg); //设备通道信息 + void addChildItem(QTreeWidgetItem *pDataItem,QTreeWidgetItem *pNoItem, QString sfileName, int sTime); + + QTreeWidgetItem *findDataItemByIP(QString sIP); + QTreeWidgetItem *findNameItemByIP(QString sIP); + QTreeWidgetItem *findNOItemByIP(QString sIP); + + QString getServerAddrByEquipNo(QString sEquipNo); // 通过设备号查找服务器地址 + + QStringList getFileListUnderDir(const QString &dirPath); + void ReadDatData(QString strPath,QString strFileName,QString strIP=""); //读取dat文件 + void ReadCsvData(QString strPath); //读取csv文件 +private: + Ui::MainWidget *ui; + QString m_strDatTime; //dat文件时间 + QString m_strDatPath; //dat文件路径 + QString m_sEquipNo; //设备号 + QString m_strDeviceName; //设备名称 + QString m_strCollectTime; //采集时间 + QVector m_vecPushData; //推送的原始数据 + QVector m_vecAllData; //推送的原始数据 + QMap> mapWaveData; + QVector m_vecWaveInfo; + QVector m_vecChildForm; //图形集合 + QVector m_vecGroupdata; //趋势数据 + WAVE_CSVDATA m_vecCsvData[32]; + QMap> m_mapChildFormToChannelID; // + QMap m_mapTabBtnToForm; //tab页关闭按钮和tab页的映射 + int m_iCount; //总时间 + int m_iCurCount; //当前时间 + int m_iRealCount; //实际读出的秒数 + bool m_backPlay; + QTimer *m_pTimer; + DataParsing *m_pDealdat; //趋势数据解析 + DEVICE_INFO m_DeviceInfo; + QString m_strIP; + CIDWUdp *m_pCIDWUdp; //UDP通信模块实例化 + AddDeviceForm *pAddDevice; + ReportForm *pReport; + SettingForm *pSetting; + QThread *m_pThread; + NetMgr *m_pNetMgr; //HTTP消息类对象 + QMap> m_mapAddrToFiles;//地址对应的子文件名 +}; +#endif // MAINWIDGET_H diff --git a/ChaosDataPlayer/MainWidget.ui b/ChaosDataPlayer/MainWidget.ui new file mode 100644 index 0000000..0824d54 --- /dev/null +++ b/ChaosDataPlayer/MainWidget.ui @@ -0,0 +1,1013 @@ + + + MainWidget + + + + 0 + 0 + 1247 + 712 + + + + MainWidget + + + #modelWgt{ + border-top:1px solid #20707f; + border-bottom:1px solid #20707f; +} + +#HideDev_Btn{border-image:url(:/images/images/imgMenuBar/B1.png);} +#addButton{border-image:url(:/images/images/imgMenuBar/B2.png);} +#refreshBtn{border-image:url(:/images/images/imgMenuBar/B3.png);} +#fileBtn{border-image:url(:/images/images/imgMenuBar/B4.png);} +#pushButton_5{border-image:url(:/images/images/imgMenuBar/B5.png);} +#pushButton_6{border-image:url(:/images/images/imgMenuBar/B6.png);} +#ReportButton{border-image:url(:/images/images/imgMenuBar/B7.png);} + +#HideDev_Btn:pressed{border-image:url(:/images/images/imgMenuBar/B1-h.png);} +#addButton:pressed{border-image:url(:/images/images/imgMenuBar/B2-h.png);} +#refreshBtn:pressed{border-image:url(:/images/images/imgMenuBar/B3-h.png);} +#fileBtn:pressed{border-image:url(:/images/images/imgMenuBar/B4-h.png);} +#pushButton_5:pressed{border-image:url(:/images/images/imgMenuBar/B5-h.png);} +#pushButton_6:pressed{border-image:url(:/images/images/imgMenuBar/B6-h.png);} +#ReportButton:pressed{border-image:url(:/images/images/imgMenuBar/B7-h.png);} + +#back3sBtn{border-image:url(:/images/images/imgPlay/B8.png);} +#back2sBtn{border-image:url(:/images/images/imgPlay/B9.png);} +#backBtn{border-image:url(:/images/images/imgPlay/B10.png);} +#PauseBtn{border-image:url(:/images/images/imgPlay/B11.png);} +#add1sBtn{border-image:url(:/images/images/imgPlay/B12.png);} +#add2sBtn{border-image:url(:/images/images/imgPlay/B13.png);} +#add3sBtn{border-image:url(:/images/images/imgPlay/B14.png);} + + +#back3sBtn:pressed{border-image:url(:/images/images/imgPlay/B8-h.png);} +#back2sBtn:pressed{border-image:url(:/images/images/imgPlay/B9-h.png);} +#backBtn:pressed{border-image:url(:/images/images/imgPlay/B10-h.png);} +#PauseBtn:pressed{border-image:url(:/images/images/imgPlay/B11-h.png);} +#add1sBtn:pressed{border-image:url(:/images/images/imgPlay/B12-h.png);} +#add2sBtn:pressed{border-image:url(:/images/images/imgPlay/B13-h.png);} +#add3sBtn:pressed{border-image:url(:/images/images/imgPlay/B14-h.png);} + + +#label_slider{border-image:url(:/images/images/imgPlay/B15.png);} + + QSlider::groove:horizontal { + border: 1px solid #999999; + height: 4px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */ + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); + margin: 2px 0; + border-radius: 1px; + } + + QSlider::handle:horizontal { + background: #fc9707; + border: 1px solid #fc9707; + width: 18px; + height: 12px; + margin: -5px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */ + border-radius: 6px; + } + +#label_value{background-color: #000002; border-radius: 6px; color:#aac3cf;} + + +#line_1, #line_2{border-image:url(:/images/images/line.png);} + +#modelBtn_TrendChart{border-image:url(:/images/images/imgDatamodel/M1-p.png);} +#modelBtn_TimeDomain{border-image:url(:/images/images/imgDatamodel/M2-p.png);} +#modelBtn_FrequencyDomain{border-image:url(:/images/images/imgDatamodel/M3-p.png);} +#modelBtn_4{border-image:url(:/images/images/imgDatamodel/M4-p.png);} +#modelBtn_5{border-image:url(:/images/images/imgDatamodel/M5-p.png);} +#modelBtn_6{border-image:url(:/images/images/imgDatamodel/M6-p.png);} +#modelBtn_7{border-image:url(:/images/images/imgDatamodel/M7-p.png);} +#modelBtn_8{border-image:url(:/images/images/imgDatamodel/M8-p.png);} +#modelBtn_spec{border-image:url(:/images/images/imgDatamodel/M9-p.png);} +#modelBtn_env{border-image:url(:/images/images/imgDatamodel/M10-p.png);} +#modelBtn_11{border-image:url(:/images/images/imgDatamodel/M11-p.png);} +#modelBtn_12{border-image:url(:/images/images/imgDatamodel/M12-p.png);} + +#modelBtn_TrendChart:hover{border-image:url(:/images/images/imgDatamodel/M1-h.png);} +#modelBtn_TimeDomain:hover{border-image:url(:/images/images/imgDatamodel/M2-h.png);} +#modelBtn_FrequencyDomain:hover{border-image:url(:/images/images/imgDatamodel/M3-h.png);} +#modelBtn_4:hover{border-image:url(:/images/images/imgDatamodel/M4-h.png);} +#modelBtn_5:hover{border-image:url(:/images/images/imgDatamodel/M5-h.png);} +#modelBtn_6:hover{border-image:url(:/images/images/imgDatamodel/M6-h.png);} +#modelBtn_7:hover{border-image:url(:/images/images/imgDatamodel/M7-h.png);} +#modelBtn_8:hover{border-image:url(:/images/images/imgDatamodel/M8-h.png);} +#modelBtn_spec:hover{border-image:url(:/images/images/imgDatamodel/M9-h.png);} +#modelBtn_env:hover{border-image:url(:/images/images/imgDatamodel/M10-h.png);} +#modelBtn_11:hover{border-image:url(:/images/images/imgDatamodel/M11-h.png);} +#modelBtn_12:hover{border-image:url(:/images/images/imgDatamodel/M12-h.png);} + +#modelBtn_TrendChart:pressed{border-image:url(:/images/images/imgDatamodel/M1-p.png);} +#modelBtn_TimeDomain:pressed{border-image:url(:/images/images/imgDatamodel/M2-p.png);} +#modelBtn_FrequencyDomain:pressed{border-image:url(:/images/images/imgDatamodel/M3-p.png);} +#modelBtn_4:pressed{border-image:url(:/images/images/imgDatamodel/M4-p.png);} +#modelBtn_5:pressed{border-image:url(:/images/images/imgDatamodel/M5-p.png);} +#modelBtn_6:pressed{border-image:url(:/images/images/imgDatamodel/M6-p.png);} +#modelBtn_7:pressed{border-image:url(:/images/images/imgDatamodel/M7-p.png);} +#modelBtn_8:pressed{border-image:url(:/images/images/imgDatamodel/M8-p.png);} +#modelBtn_spec:pressed{border-image:url(:/images/images/imgDatamodel/M9-p.png);} +#modelBtn_env:pressed{border-image:url(:/images/images/imgDatamodel/M10-p.png);} +#modelBtn_11:pressed{border-image:url(:/images/images/imgDatamodel/M11-p.png);} +#modelBtn_12:pressed{border-image:url(:/images/images/imgDatamodel/M12-p.png);} + + + +#rightWgt{border: 1px solid #5c7688; } + + + + 0 + + + 4 + + + 0 + + + 4 + + + 0 + + + + + + 0 + 42 + + + + + 16777215 + 42 + + + + + 10 + + + 5 + + + 5 + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 打开/隐藏终端列表 + + + + + + + + + + + 2 + 32 + + + + + 2 + 32 + + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 增加终端 + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 刷新终端列表 + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 打开文件 + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + DAT转CSV + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 退出当前DAT文件 + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 导出诊断报告 + + + + + + + + + + true + + + + 18 + 18 + + + + + 18 + 18 + + + + S + + + + + + + + 2 + 32 + + + + + 2 + 32 + + + + + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 显示第一秒 + + + + + + true + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 播放上一秒 + + + + + + true + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 倒放 + + + + + + true + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 暂停 + + + + + + + + + true + + + false + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 播放 + + + + + + true + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 播放下一秒 + + + + + + true + + + + + + + + 18 + 18 + + + + + 18 + 18 + + + + 显示最后一秒 + + + + + + true + + + + + + + Qt::Horizontal + + + + + + + + 44 + 20 + + + + + 44 + 20 + + + + + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 523 + 20 + + + + + + + + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + + 16 + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 趋势图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 时域图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 频域图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 瀑布图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 包络图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 轴心轨迹图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 伯德图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 轴心位置图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 极坐标 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + 全谱图 + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + crank angle + + + + + + + + + + false + + + + 36 + 36 + + + + + 36 + 36 + + + + + + + + + + + Qt::Horizontal + + + + 594 + 20 + + + + + + + + + + + + + + Qt::Horizontal + + + + + 234 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + true + + + + 1 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + + diff --git a/ChaosDataPlayer/Mqttclient.cpp b/ChaosDataPlayer/Mqttclient.cpp new file mode 100644 index 0000000..3bcf81c --- /dev/null +++ b/ChaosDataPlayer/Mqttclient.cpp @@ -0,0 +1,160 @@ +#include "MqttClient.h" + +MqttClient::MqttClient(QObject *parent) : QObject(parent) +{ + +} + +void MqttClient::onMQTT_Connected() + { + qDebug()<< "doConnected" <pushButtonPusblish->setEnabled(true); + ui->pushButtonSubscribe->setEnabled(true); + ackStatus = "Connection Accepted"; + break; + case QMQTT::CONNACK_PROTO_VER: + ackStatus = "Connection Refused: unacceptable protocol version"; + break; + case QMQTT::CONNACK_INVALID_ID: + ackStatus = "Connection Refused: identifier rejected"; + break; + case QMQTT::CONNACK_SERVER: + ackStatus = "Connection Refused: server unavailable"; + break; + case QMQTT::CONNACK_CREDENTIALS: + ackStatus = "Connection Refused: bad user name or password"; + break; + case QMQTT::CONNACK_AUTH: + ackStatus = "Connection Refused: not authorized"; + break; + } + log(tr("connacked: %1, %2").arg(ack).arg(ackStatus)); + */ + } + + + void MqttClient::onMQTT_error(QMQTT::ClientError err) + { + //todo: should emit on server suback + + QString errInfo; + + switch(err) { + // 0 The connection was refused by the peer (or timed out). + case QAbstractSocket::ConnectionRefusedError: + errInfo = tr("Connection Refused"); + // 1 The remote host closed the connection. Note that the client socket (i.e., this socket) will be closed after the remote close notification has been sent. + case QAbstractSocket::RemoteHostClosedError: + errInfo = tr("Remote Host Closed"); + // 2 The host address was not found. + case QAbstractSocket::HostNotFoundError: + errInfo = tr("Host Not Found Error"); + // 3 The socket operation failed because the application lacked the required privileges. + case QAbstractSocket::SocketAccessError: + errInfo = tr("Socket Access Error"); + // 4 The local system ran out of resources (e.g., too many sockets). + case QAbstractSocket::SocketResourceError: + errInfo = tr("Socket Resource Error"); + // 5 The socket operation timed out. + case QAbstractSocket::SocketTimeoutError: + errInfo = tr("Socket Timeout Error"); + default: + errInfo = tr("Socket Error"); + } + + qDebug()<< errInfo <publish(message); + } +void MqttClient::subscribed(QString strTopic) + { + + qDebug()<< "subscribed" <subscribe(strTopic); + } +void MqttClient::ConnectMQTT(QString strIP) +{ + m_client = new QMQTT::Client(QHostAddress(strIP),1883); + + //m_client->setHost(QHostAddress("192.168.1.156")); + //m_client->setPort(51613); + //m_client->setUsername("chaos"); + //m_client->setPassword("HSD272*#xkd"); + m_client->connectToHost(); + + connect(m_client, SIGNAL(connected()), this, SLOT(onMQTT_Connected())); + //todo: should emit on server suback + //connect(_client, SIGNAL(connacked(quint8)), this, SLOT(onMQTT_Connacked(quint8))); + connect(m_client, SIGNAL(error(QMQTT::ClientError)), this, SLOT(onMQTT_error(QMQTT::ClientError))); + + //slots changes + //API: void published(const QMQTT::Message& message); + connect(m_client,SIGNAL(published(const QMQTT::Message &)),this,SLOT(onMQTT_Published(const QMQTT::Message &))); + + //todo: should emit on server suback + //connect(_client, SIGNAL(pubacked(quint8, quint16)), this, SLOT(onMQTT_Pubacked(quint8, quint16))); + connect(m_client, SIGNAL(received(const QMQTT::Message &)), this, SLOT(onMQTT_Received(const QMQTT::Message &))); + connect(m_client, SIGNAL(subscribed(const QString &)), this, SLOT(onMQTT_subscribed(const QString &))); + +} diff --git a/ChaosDataPlayer/Mqttclient.h b/ChaosDataPlayer/Mqttclient.h new file mode 100644 index 0000000..c84034d --- /dev/null +++ b/ChaosDataPlayer/Mqttclient.h @@ -0,0 +1,34 @@ +#ifndef MQTTCLIENT_H +#define MQTTCLIENT_H + +#include +#include "qmqtt.h" +#include "global.h" + +class MqttClient : public QObject +{ + Q_OBJECT +public: + explicit MqttClient(QObject *parent = nullptr); + void ConnectMQTT(QString strIP); + QMQTT::Client *m_client; + void Push(const QMQTT::Message &message); + void subscribed(QString strTopic); +public slots: + void onMQTT_Connected(); + void onMQTT_Connacked(quint8 ack); + void onMQTT_error(QMQTT::ClientError err); + void onMQTT_Published(const QMQTT::Message &message); + void onMQTT_Pubacked(quint8 type, quint16 msgid); + void onMQTT_Received(const QMQTT::Message &message); + void onMQTT_subscribed(const QString &topic); + void onMQTT_subacked(quint16 msgid, quint8 qos); + void onMQTT_unsubscribed(const QString &topic); + void onMQTT_unsubacked(quint16 msgid); + void onMQTT_disconnected(); +signals: + void WaveData_sig(QByteArray); +}; + +#endif // MQTTCLIENT_H + diff --git a/ChaosDataPlayer/NetMgr.cpp b/ChaosDataPlayer/NetMgr.cpp new file mode 100644 index 0000000..5146a8f --- /dev/null +++ b/ChaosDataPlayer/NetMgr.cpp @@ -0,0 +1,358 @@ +#include "NetMgr.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum{ + HTTP_CMD_ID = QNetworkRequest::User+100, +}; + + +NetMgr &NetMgr::instance() +{ + static NetMgr ins; + return ins; +} + +NetMgr::NetMgr(QObject *parent) + :QObject(parent) + ,m_netMgr(new QNetworkAccessManager(this)) +{ + qDebug()<supportedSchemes(); + connect(m_netMgr,SIGNAL(finished(QNetworkReply *)),SLOT(httpFinished(QNetworkReply *))); +} + +NetMgr::~NetMgr() +{ +} + +void NetMgr::RequestFileList(const QString &sAddr) +{ + QString sUrl = QString("http://%1%2").arg(sAddr).arg("/cgi-bin/General.cgi"); + qDebug()<<"url[RequestLicList]:"< &postData) +{ + AddMultiPartSignature(req, postData); + qDebug()<<"suport ssl"<append(textPart); + } + + + QNetworkReply* pReply = m_netMgr->post(req,multiPart); + multiPart->setParent(pReply); + + connect(pReply, QOverload::of(&QNetworkReply::error),[=](QNetworkReply::NetworkError err) + { + qDebug()<<"net error:"; + qDebug()<errorString(); + //pReply->deleteLater(); + }); + +} + +void NetMgr::PostJson(QNetworkRequest &req, QJsonObject &postData) +{ + AddJsonSignature(req, postData); + req.setHeader(QNetworkRequest::ContentTypeHeader,"application/json"); + QSslConfiguration config; + config.setProtocol(QSsl::TlsV1SslV3); + config.setPeerVerifyMode(QSslSocket::VerifyNone); + req.setSslConfiguration(config); + + //QString sBody; + QByteArray bzData = QJsonDocument(postData).toJson(QJsonDocument::Compact); + QNetworkReply* pReply = m_netMgr->post(req,bzData); + + connect(pReply, QOverload::of(&QNetworkReply::error),[=](QNetworkReply::NetworkError err) + { + qDebug()<<"error:"; + qDebug()<errorString(); + //pReply->deleteLater(); + }); +} + +void NetMgr::PostData(QNetworkRequest &req, QByteArray &postData) +{ + AddDataSignature(req, postData); + req.setHeader(QNetworkRequest::ContentTypeHeader,"application/json"); + QSslConfiguration config; + config.setProtocol(QSsl::TlsV1SslV3); + config.setPeerVerifyMode(QSslSocket::VerifyNone); + req.setSslConfiguration(config); + + QNetworkReply* pReply = m_netMgr->post(req,postData); + + connect(pReply, QOverload::of(&QNetworkReply::error),[=](QNetworkReply::NetworkError err) + { + qDebug() << "error:"; + qDebug() << pReply->errorString(); + //pReply->deleteLater(); + }); +} + +void NetMgr::DownLoad(QNetworkRequest &req, const QString &sFileSavePath) +{ + QSslConfiguration config; + config.setProtocol(QSsl::TlsV1SslV3); + config.setPeerVerifyMode(QSslSocket::VerifyNone); + req.setSslConfiguration(config); + + QString sDir = QFileInfo(sFileSavePath).dir().path(); + QDir dir(sDir); + if(!dir.exists()) + { + if(!dir.mkpath(sDir)) + { + qDebug()<<"mkpath failed"< pFile(new QFile(sFileSavePath)); + if(!pFile->open(QIODevice::WriteOnly|QIODevice::Truncate)) + { + + qDebug()<errorString()<get(req); + m_mpDownload[pReply] = pFile; + pFile->setParent(pReply); + connect(pReply,&QNetworkReply::readyRead,[=] + { + if(!pFile.isNull()) + { + pFile->write(pReply->readAll()); + } + + }); + + connect(pReply, QOverload::of(&QNetworkReply::error),[=](QNetworkReply::NetworkError err) + { + //qDebug()<<"error:"; + //qDebug()<errorString(); + if(!pFile.isNull()) + { + pFile->close(); + QFile::remove(pFile->fileName()); + } + pReply->deleteLater(); + }); +} + +void NetMgr::GetData(QNetworkRequest &req) +{ + //req.setHeader(QNetworkRequest::ContentTypeHeader,"application/json"); + QSslConfiguration config; + config.setProtocol(QSsl::TlsV1SslV3); + config.setPeerVerifyMode(QSslSocket::VerifyNone); + req.setSslConfiguration(config); + + //QString sBody; + + QNetworkReply* pReply = m_netMgr->get(req); + + connect(pReply, QOverload::of(&QNetworkReply::error),[=](QNetworkReply::NetworkError err) + { + //qDebug()<<"error:"; + //qDebug()<errorString(); + //pReply->deleteLater(); + }); +} + + +void NetMgr::AddMultiPartSignature(QNetworkRequest &req, QMap &postData) +{ + QString sSrcKey; + QStringList listParams; + foreach(const QString& sKey, postData.keys()) + { + listParams << QString("%1=%2").arg(sKey, postData.value(sKey)); + } + sSrcKey = listParams.join("&"); + AddSignature(req, sSrcKey); + +} + +void NetMgr::AddJsonSignature(QNetworkRequest &req, QJsonObject &postData) +{ + QString sSrcKey; + //if(!postData.isEmpty()) + { + sSrcKey = QJsonDocument(postData).toJson(QJsonDocument::Compact); + } + + AddSignature(req, sSrcKey); +} + +void NetMgr::AddDataSignature(QNetworkRequest &req, QByteArray &postData) +{ + Q_UNUSED(postData) + QString sSrcKey; + AddSignature(req, sSrcKey); +} + +void NetMgr::AddSignature(QNetworkRequest &req, QString& sSrcKey) +{ + qDebug() << sSrcKey; + QString sToken = ""; + if (req.hasRawHeader("commtoken")) + { + sToken = req.rawHeader("commtoken"); + } + else if (req.hasRawHeader("accesstoken")) + { + sToken = req.rawHeader("accesstoken"); + } + QString sTimeStamp = QString::number(QDateTime::currentMSecsSinceEpoch()); + if (sSrcKey.isEmpty()) + { + sSrcKey = QString("timestamp=%1").arg(sTimeStamp); + } + else { + sSrcKey = sSrcKey + QString("×tamp=%1").arg(sTimeStamp); + } + + sSrcKey = QUrl::toPercentEncoding(sSrcKey); + QByteArray key = sToken.toUtf8(); + QByteArray message = sSrcKey.toUtf8(); + QByteArray bzSign = QMessageAuthenticationCode::hash(message, key, QCryptographicHash::Sha256).toHex(); + bzSign = bzSign.toBase64(); + req.setRawHeader("timestamp", sTimeStamp.toUtf8()); + req.setRawHeader("signature", bzSign); +} + +void NetMgr::httpFinished(QNetworkReply *reply) +{ + if (reply->error() == QNetworkReply::NoError) + { + if (m_mpDownload.contains(reply)) + { + QString sAddr = reply->request().attribute((QNetworkRequest::Attribute)HTTP_CMD_ID).toString(); + reply->waitForReadyRead(3000); + QFile* pFile = m_mpDownload.value(reply); + //emit sigNetMgr(sAddr, pFile->fileName()); + m_mpDownload.remove(reply); + } + else + { + QString sAddr = reply->request().attribute((QNetworkRequest::Attribute)HTTP_CMD_ID).toString(); + //qDebug()<<"nCmdId:"<readAll(); + QString sPath = reply->request().url().path(); + parseData(bzData, sPath, sAddr); + } + + } + else + {//错误 + + } + + reply->deleteLater(); +} + +void NetMgr::parseData(const QByteArray &szData, const QString &sUrlPath, QString sAddr) +{ + qDebug() << sUrlPath << szData; + QJsonDocument doc = QJsonDocument::fromJson(szData); + QJsonObject obj = doc.object(); + QVariant var; + var.setValue(obj); + + emit sigNetMgr(sAddr, var); +} + +void NetMgr::setReqUserAttr(QNetworkRequest &req, QVariant attr) +{ + req.setAttribute((QNetworkRequest::Attribute)HTTP_CMD_ID,attr); +} + + diff --git a/ChaosDataPlayer/NetMgr.h b/ChaosDataPlayer/NetMgr.h new file mode 100644 index 0000000..d8c8481 --- /dev/null +++ b/ChaosDataPlayer/NetMgr.h @@ -0,0 +1,61 @@ +#ifndef NETMGR_H +#define NETMGR_H +#include +#include +#include + +class QNetworkAccessManager; +class QNetworkReply; +class QFile; + +class QNetworkRequest; + +class NetMgr:public QObject +{ + Q_OBJECT +signals: + void sigNetMgr(QString sAddr,const QVariant& variant); +public: + static NetMgr& instance(); + NetMgr(QObject* parent = nullptr); + ~NetMgr(); +public: + //ļб + void RequestFileList(const QString& sAddr); + //ļϢ + void RequestFileInfo(const QString& sAddr); + //ļ + void RequestDownload(const QString& sUrl, const QString& sFileName, const QString& sFileSavePath); + void RequestChannelInfo(const QString& sAddr); +public: + //ʽ + void PostMultiPart(QNetworkRequest& req, QMap &postData); + void PostJson(QNetworkRequest& req, QJsonObject &postData); + void PostData(QNetworkRequest& req, QByteArray &postData); + void DownLoad(QNetworkRequest& req,const QString& sFileSavePath); + void GetData(QNetworkRequest& req); + + void AddMultiPartSignature(QNetworkRequest& req, QMap &postData); + void AddJsonSignature(QNetworkRequest& req, QJsonObject &postData); + void AddDataSignature(QNetworkRequest& req, QByteArray &postData); + void AddSignature(QNetworkRequest& req, QString &sSrcKey); + +private slots: + //Ӧ + void httpFinished(QNetworkReply * reply); +private: + // + void parseData(const QByteArray& szData, const QString& sUrlPath, QString sAddr); + + //ÿHTTPһIPַ˭HTTP + void setReqUserAttr(QNetworkRequest& req,QVariant attr); + +private: + + QNetworkAccessManager *m_netMgr; + QMap m_mpDownload; +}; + + + +#endif // NETMGR_H diff --git a/ChaosDataPlayer/PlayWaveSound.cpp b/ChaosDataPlayer/PlayWaveSound.cpp new file mode 100644 index 0000000..37ec7f5 --- /dev/null +++ b/ChaosDataPlayer/PlayWaveSound.cpp @@ -0,0 +1,170 @@ +#include "PlayWaveSound.h" +#include "portaudio.h" +#include + +//#define NUM_SECONDS (11) +//#define SAMPLE_RATE (65536) +//#define FRAMES_PER_BUFFER (1024) + +//#ifndef M_PI +//#define M_PI (3.14159265) +//#endif + +//#define TABLE_SIZE (200) + +//typedef struct { +// QString channelId; +// QVector wavedata; +//} WAVE_CSVDATA1; + +//WAVE_CSVDATA1 m_vecCsvData[32]; + + +PlayWaveSound::PlayWaveSound(QObject *parent) : QObject(parent) +{ + Init(); +} + +PlayWaveSound::~PlayWaveSound() +{ + +} +void PlayWaveSound::Init() +{ +// PaStreamParameters outputParameters; +// PaStream *stream; +// PaError err; +// float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */ +// float sine[TABLE_SIZE]; /* sine wavetable */ +// float *Data = NULL; +// Data = (float*)malloc(4); +// int left_phase = 0; +// int right_phase = 0; +// int left_inc = 1; +// int right_inc = 1; /* higher pitch so we can distinguish left and right. */ +// int i, j, k; +// int bufferCount; + +// printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); + +// QFile file("e:\\22.csv"); +// if (!file.open(QIODevice::ReadOnly)) +// { +// qDebug() << "::MainWidget::ReadDatData() cannot open file for read"; +// } +// QTextStream * out = new QTextStream(&file);//文本流 +// QStringList tempOption = out->readAll().split("\n");//每行以\n区分 +// qDebug() << "tempOption.count " << tempOption.count() << endl; +// QStringList tempbar; +// for(int i = 1 ; i < tempOption.count()-1 ; i++) +// { +// tempbar = tempOption.at(i).split(",");//一行中的单元格以,区分 +// for(int j = 0; j < tempbar.size();j++) +// { +// m_vecCsvData[j].wavedata.push_back(tempbar.at(j).toFloat()/1000); +// m_vecCsvData[j].channelId = QString(j+1); +// } +// } +// qDebug() << "tempbar " << m_vecCsvData[1].wavedata.size() << endl; +// file.close();// + + + +// for( i=0; idefaultLowOutputLatency; // Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; +// outputParameters.hostApiSpecificStreamInfo = NULL; + +// err = Pa_OpenStream( +// &stream, +// NULL, /* no input */ +// &outputParameters, +// SAMPLE_RATE, +// FRAMES_PER_BUFFER, +// paClipOff, /* we won't output out of range samples so don't bother clipping them */ +// NULL, /* no callback, use blocking API */ +// NULL ); /* no callback, so no callback userData */ +// if( err != paNoError ) goto error; + + +// printf( "Play 3 times, higher each time.\n" ); + +// //for( k=0; k < 3; ++k ) +// { +// err = Pa_StartStream( stream ); +// if( err != paNoError ) goto error; + +// printf("Play for %d seconds.\n", NUM_SECONDS ); + +// bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER); + +// int count = 0; +// printf("bufferCount %d .\n", bufferCount ); +// for( i=0; i < bufferCount; i++ ) +// { +// for( j=0; j < FRAMES_PER_BUFFER; j++ ) +// { +// count = j + i*FRAMES_PER_BUFFER; +// buffer[j][0] = m_vecCsvData[0].wavedata[count]; /* left */ +// buffer[j][1] = m_vecCsvData[0].wavedata[count]; /* right */ +// //buffer[j][0] = m_vecCsvData[4].wavedata[left_phase]; /* left */ +// //buffer[j][1] = m_vecCsvData[4].wavedata[right_phase]; /* right */ +// left_phase += left_inc; +// if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE; +// right_phase += right_inc; +// if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE; + +// } + +// err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER ); +// if( err != paNoError ) goto error; +// } +// printf("count = %d\n",count); +// err = Pa_StopStream( stream ); +// if( err != paNoError ) goto error; + +// // ++left_inc; +// // ++right_inc; + +// Pa_Sleep( 1000 ); +// } + +// err = Pa_CloseStream( stream ); +// if( err != paNoError ) goto error; + +// Pa_Terminate(); +// printf("Test finished.\n"); +// qDebug() << "PlaySound end" << endl; +// return ; + +// error: +// fprintf( stderr, "An error occurred while using the portaudio stream\n" ); +// fprintf( stderr, "Error number: %d\n", err ); +// fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); +// // Print more information about the error. +// if( err == paUnanticipatedHostError ) +// { +// const PaHostErrorInfo *hostErrorInfo = Pa_GetLastHostErrorInfo(); +// fprintf( stderr, "Host API error = #%ld, hostApiType = %d\n", hostErrorInfo->errorCode, hostErrorInfo->hostApiType ); +// fprintf( stderr, "Host API error = %s\n", hostErrorInfo->errorText ); +// } +// Pa_Terminate(); + +// return ; +} diff --git a/ChaosDataPlayer/PlayWaveSound.h b/ChaosDataPlayer/PlayWaveSound.h new file mode 100644 index 0000000..cc03788 --- /dev/null +++ b/ChaosDataPlayer/PlayWaveSound.h @@ -0,0 +1,18 @@ +#ifndef PLAYWAVESOUND_H +#define PLAYWAVESOUND_H + +#include +#include "global.h" + +class PlayWaveSound : public QObject +{ + Q_OBJECT +public: + explicit PlayWaveSound(QObject *parent = nullptr); + ~PlayWaveSound(); + void Init(); +signals: + +}; + +#endif // PLAYWAVESOUND_H diff --git a/ChaosDataPlayer/Reportform.cpp b/ChaosDataPlayer/Reportform.cpp new file mode 100644 index 0000000..7fa0677 --- /dev/null +++ b/ChaosDataPlayer/Reportform.cpp @@ -0,0 +1,74 @@ +#include "Reportform.h" +#include "ui_Reportform.h" +#include +#include + +ReportForm::ReportForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::ReportForm) +{ + ui->setupUi(m_pMainWgt); + resize(700,650); + setWindowTitle("诊断报告"); + m_strReportName = ""; + m_filePath = ""; + connect(ui->ChoosePath_Btn, SIGNAL(clicked()), this, SLOT(ChoosePath())); + connect(ui->PDF_radioButton, SIGNAL(toggled(bool)),this,SLOT(ChoosePDF(bool))); + connect(ui->Word_radioButton, SIGNAL(toggled(bool)),this,SLOT(ChooseWord(bool))); + connect(ui->Report_Btn, SIGNAL(clicked()),this,SLOT(Report())); + + ui->Result_Edit->setPlaceholderText("请输入..."); + +} + +ReportForm::~ReportForm() +{ + delete ui; +} +void ReportForm::InitReport(QString path,QStringList& strImagePathList,QString ReportName,REPORT_INFO& reportInfo) +{ + _reportInfo = reportInfo; + ui->ReportPath_Edit->setText(path); + m_strReportName = ReportName; + m_filePath = path; + strImagePath = strImagePathList; +} + +void ReportForm::ChoosePath() +{ + QString dirpath = QFileDialog::getExistingDirectory(this, QStringLiteral("选择目录"), "./", QFileDialog::ShowDirsOnly); + if(dirpath.isEmpty()) dirpath = QDir::currentPath(); + ui->ReportPath_Edit->setText(dirpath + "/" + m_strReportName); + m_filePath = dirpath + "\\" + m_strReportName; +} +void ReportForm::ChoosePDF(bool flag) +{ + if(flag){ + ui->Result_Edit->setVisible(true); + ui->label_2->setText("诊断结果及建议:"); + } + +} +void ReportForm::ChooseWord(bool flag) +{ + if(flag){ + ui->Result_Edit->setVisible(false); + ui->label_2->setText("提示:请在Word中输入诊断建议!"); + } +} + +void ReportForm::Report() +{ + + QString strResult =ui->Result_Edit->document()->toPlainText(); + qDebug() << "Report:" << strResult; + QStringList strResultList = strResult.split(QRegExp("[\n]"),QString::SkipEmptyParts); + if(ui->PDF_radioButton->isChecked()) + { + emit ReportPDF(strResultList,m_filePath); + + }else{ + cp.GetReport(_reportInfo,strImagePath); + } + +} diff --git a/ChaosDataPlayer/Reportform.h b/ChaosDataPlayer/Reportform.h new file mode 100644 index 0000000..a507b17 --- /dev/null +++ b/ChaosDataPlayer/Reportform.h @@ -0,0 +1,40 @@ +#ifndef REPORTFORM_H +#define REPORTFORM_H + +#include +#include "BaseWgt.h" +#include "CreateReport.h" +#include "msgbox.h" +#include "QMessageBox" +#include "global.h" + +namespace Ui { +class ReportForm; +} + +class ReportForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit ReportForm(QWidget *parent = nullptr); + ~ReportForm(); + void InitReport(QString Path,QStringList& strImagePathList,QString ReportName,REPORT_INFO& reportInfo); +private slots: + void ChoosePath(); + void ChoosePDF(bool flag); + void ChooseWord(bool flag); + void Report(); +private: + Ui::ReportForm *ui; + QString m_strReportName; + QString m_filePath; + CreateReport cp; + REPORT_INFO _reportInfo; + QStringList strImagePath; +signals: + void ReportPDF(QStringList strResult,QString filePath); + +}; + +#endif // REPORTFORM_H diff --git a/ChaosDataPlayer/Reportform.ui b/ChaosDataPlayer/Reportform.ui new file mode 100644 index 0000000..07ded54 --- /dev/null +++ b/ChaosDataPlayer/Reportform.ui @@ -0,0 +1,296 @@ + + + ReportForm + + + + 0 + 0 + 742 + 528 + + + + Form + + + + 0 + + + 4 + + + 0 + + + 4 + + + 0 + + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + + 10 + + + 5 + + + 5 + + + + + 报告路径: + + + + + + + + 200 + 30 + + + + + 16777215 + 30 + + + + background-color: rgb(211,211,211); +color: rgb(0, 0, 0); +border-width:0;border-style:outset; +text-align:center; + + + + + + + + + 100 + 30 + + + + background-color: rgb(69, 90, 108); + + + 选择路径 + + + + + + + + + + + 500 + 100 + + + + + 16777215 + 100 + + + + + + 210 + 70 + 80 + 30 + + + + + 80 + 30 + + + + + 80 + 30 + + + + QRadioButton::indicator{ + width:15px; + height:15px; + border-radius:8px; + border-style: solid; + border-width: 1px; + border-color: black; +} +QRadioButton::indicator:checked { + background-color:orange; +} +QRadioButton::indicator:unchecked { + background-color:rgb(255, 255, 255); +} + + + + PDF报告 + + + true + + + + + + 390 + 70 + 80 + 30 + + + + + 80 + 30 + + + + + 80 + 30 + + + + QRadioButton::indicator{ + width:15px; + height:15px; + border-radius:8px; + border-style: solid; + border-width: 1px; + border-color: black; +} +QRadioButton::indicator:checked { + background-color:orange; +} +QRadioButton::indicator:unchecked { + background-color:rgb(255, 255, 255); +} + + + + Word报告 + + + + + + + + + + 40 + 60 + 300 + 30 + + + + + 300 + 30 + + + + + 300 + 30 + + + + 诊断结果及建议: + + + + + + 40 + 100 + 600 + 200 + + + + + 600 + 200 + + + + + 600 + 200 + + + + background-color: rgb(211,211,211); +color: rgb(0, 0, 0); + + + + + + + 300 + 330 + 100 + 30 + + + + + 100 + 30 + + + + + 100 + 30 + + + + background-color: rgb(69, 90, 108); + + + 导出 + + + + + + + + + diff --git a/ChaosDataPlayer/SH_MySingleton.hpp b/ChaosDataPlayer/SH_MySingleton.hpp new file mode 100644 index 0000000..d70b24a --- /dev/null +++ b/ChaosDataPlayer/SH_MySingleton.hpp @@ -0,0 +1,23 @@ +#ifndef MYSINGLETON_H_ +#define MYSINGLETON_H_ + +template +class MySingleton { +public: + static T* instance() { + static T _instance; + return &_instance; + } + ; +protected: + MySingleton() { + } + ; + virtual ~MySingleton() { + } + ; + MySingleton(const MySingleton &); + MySingleton& operator=(const MySingleton &); +}; + +#endif diff --git a/ChaosDataPlayer/SetScalesForm.ui b/ChaosDataPlayer/SetScalesForm.ui new file mode 100644 index 0000000..f03ec33 --- /dev/null +++ b/ChaosDataPlayer/SetScalesForm.ui @@ -0,0 +1,215 @@ + + + SetScalesForm + + + + 0 + 0 + 512 + 300 + + + + Form + + + + + + + 0 + 200 + + + + + + 170 + 50 + 51 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 113 + 50 + 31 + 31 + + + + X + + + + + + 300 + 50 + 51 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 240 + 60 + 54 + 12 + + + + ----- + + + + + + 170 + 100 + 51 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 113 + 100 + 31 + 31 + + + + Y + + + + + + 300 + 100 + 51 + 31 + + + + background-color: rgb(28, 28, 36); +border-width:0;border-style:outset; +text-align:center; + + + + + + + 240 + 110 + 54 + 12 + + + + ----- + + + + + + 180 + 20 + 54 + 21 + + + + 起始 + + + + + + 310 + 20 + 54 + 21 + + + + 结束 + + + + + + + + + 0 + 30 + + + + + + 270 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 确认 + + + + + + 370 + 40 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 取消 + + + + + + + + + diff --git a/ChaosDataPlayer/SetScalesform.cpp b/ChaosDataPlayer/SetScalesform.cpp new file mode 100644 index 0000000..ec8c965 --- /dev/null +++ b/ChaosDataPlayer/SetScalesform.cpp @@ -0,0 +1,57 @@ +#include "SetScalesform.h" +#include "ui_SetScalesForm.h" +#include "QMessageBox" +#include + +SetScalesForm::SetScalesForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::SetScalesForm) +{ + ui->setupUi(m_pMainWgt); + resize(500,320); + setWindowTitle("设置坐标范围"); + connect(ui->Btn_OK, SIGNAL(clicked()), this, SLOT(SetScales())); + connect(ui->Btn_Cancel, SIGNAL(clicked()), this, SLOT(Cancel())); + QRegExp rx("^(-?[0-9])|(-?\\d+)(\.\\d+)$"); + QRegExpValidator *validator = new QRegExpValidator(rx, this); + ui->lineEdit->setValidator(validator); + ui->lineEdit_2->setValidator(validator); + ui->lineEdit_3->setValidator(validator); + ui->lineEdit_4->setValidator(validator); +} + +SetScalesForm::~SetScalesForm() +{ + delete ui; +} +void SetScalesForm::Cancel() +{ + this->close(); +} +void SetScalesForm::SetScales() +{ + QString Xstart = ui->lineEdit->text(); + QString Xend = ui->lineEdit_2->text(); + QString Ystart = ui->lineEdit_3->text(); + QString Yend = ui->lineEdit_4->text(); + if((Xstart.length() == 0 || Xend.length() == 0) && (Ystart.length() == 0 || Yend.length() == 0)) + { + MyMsgBox(QMessageBox::Question,"问题","请输入正确的坐标信息"); + return; + } + if(Xstart.toFloat() > Xend.toFloat() || Ystart.toFloat() > Yend.toFloat()) + { + MyMsgBox(QMessageBox::Question,"问题","请输入正确的坐标信息"); + return; + } + emit sgSetScales(Xstart+","+Xend+","+Ystart + "," + Yend); + this->close(); +} +void SetScalesForm::keyPressEvent(QKeyEvent *event) +{ + //Enter事件好像这两个都要写,只写event->key() == Qt::Key_Enter,无法实现 + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + SetScales(); + } +} diff --git a/ChaosDataPlayer/SetScalesform.h b/ChaosDataPlayer/SetScalesform.h new file mode 100644 index 0000000..b8b727f --- /dev/null +++ b/ChaosDataPlayer/SetScalesform.h @@ -0,0 +1,31 @@ +#ifndef SETSCALESFORM_H +#define SETSCALESFORM_H + +#include +#include "BaseWgt.h" +#include +#include "msgbox.h" + +namespace Ui { +class SetScalesForm; +} + +class SetScalesForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit SetScalesForm(QWidget *parent = nullptr); + ~SetScalesForm(); +private: + Ui::SetScalesForm *ui; +private slots: + void SetScales(); + void Cancel(); +protected: + virtual void keyPressEvent(QKeyEvent *event); +signals: + void sgSetScales(QString); +}; + +#endif // SETSCALESFORM_H diff --git a/ChaosDataPlayer/SettingForm.cpp b/ChaosDataPlayer/SettingForm.cpp new file mode 100644 index 0000000..22889f1 --- /dev/null +++ b/ChaosDataPlayer/SettingForm.cpp @@ -0,0 +1,51 @@ +#include "SettingForm.h" +#include "ui_SettingForm.h" +#include +#include "global.h" + +SettingForm::SettingForm(QWidget *parent) : + BaseWgt(parent), + ui(new Ui::SettingForm) +{ + ui->setupUi(m_pMainWgt); + resize(500,400); + setWindowTitle("参数配置"); + //ui->groupBox->setStyleSheet("background:transparent;border:1px solid red;"); + ui->groupBox->setStyleSheet(QObject::tr("#groupBox{border: 1px solid #5c7688;}")); + + //ui->comboBox->setStyleSheet(""); + QListView* listView = new QListView(); + ui->comboBox->setView(listView); + + ui->comboBox->insertItem(0,"上升沿"); + ui->comboBox->insertItem(1,"下降沿"); + + QRegExp rx("^(-?[0]|-?[1-9][0-9]{0,5})(?:\\.\\d{1,4})?$|(^\\t?$)"); + QRegExpValidator *validator = new QRegExpValidator(rx, this); + ui->Hysteresis_lineEdit->setValidator(validator); + ui->Key_lineEdit->setValidator(validator); + ui->TriggerValue_lineEdit->setValidator(validator); + + connect(ui->OK_Btn,SIGNAL(clicked()),this,SLOT(Confirm())); + +} + +SettingForm::~SettingForm() +{ + delete ui; +} + +void SettingForm::Confirm() +{ + if(ui->TriggerValue_lineEdit->text().isEmpty() || ui->Key_lineEdit->text().isEmpty() || ui->Hysteresis_lineEdit->text().isEmpty()) + { + MyMsgBox(QMessageBox::Question,"警告","请输入完整信息"); + return; + } + global::rotatingSpeed.iTrigger = ui->comboBox->currentIndex(); + global::rotatingSpeed.iTriggerValue = ui->TriggerValue_lineEdit->text().toInt(); + global::rotatingSpeed.iKeyCount = ui->Key_lineEdit->text().toInt(); + global::rotatingSpeed.iHysteresis = ui->Hysteresis_lineEdit->text().toInt(); + + this->close(); +} diff --git a/ChaosDataPlayer/SettingForm.h b/ChaosDataPlayer/SettingForm.h new file mode 100644 index 0000000..27b8662 --- /dev/null +++ b/ChaosDataPlayer/SettingForm.h @@ -0,0 +1,27 @@ +#ifndef SETTINGFORM_H +#define SETTINGFORM_H + +#include +#include "BaseWgt.h" +#include "msgbox.h" +#include "QMessageBox" + +namespace Ui { +class SettingForm; +} + +class SettingForm : public BaseWgt +{ + Q_OBJECT + +public: + explicit SettingForm(QWidget *parent = nullptr); + ~SettingForm(); + +public slots: + void Confirm(); +private: + Ui::SettingForm *ui; +}; + +#endif // SETTINGFORM_H diff --git a/ChaosDataPlayer/SettingForm.ui b/ChaosDataPlayer/SettingForm.ui new file mode 100644 index 0000000..4a62c29 --- /dev/null +++ b/ChaosDataPlayer/SettingForm.ui @@ -0,0 +1,176 @@ + + + SettingForm + + + + 0 + 0 + 667 + 343 + + + + Form + + + + + + + + 10 + 10 + 561 + 311 + + + + + + 180 + 280 + 75 + 23 + + + + background-color: rgb(69, 90, 108); + + + 确定 + + + + + + 10 + 10 + 221 + 241 + + + + border-color: rgb(85, 255, 127); + + + 转速 + + + + + 20 + 80 + 71 + 31 + + + + 触发阈值: + + + + + + 20 + 160 + 81 + 31 + + + + Hysteresis: + + + + + + 120 + 40 + 69 + 31 + + + + color: rgb(0, 0, 0); +QComboBox { min-height: 30px; min-width: 60px;} +QComboBox QAbstractItemView::item { min-height: 30px; min-width: 60px;} + + + + + + 20 + 40 + 54 + 21 + + + + 触发沿: + + + + + + 120 + 80 + 71 + 31 + + + + background-color: rgb(211,211,211); +color: rgb(0, 0, 0); + + + + + + + 120 + 160 + 71 + 31 + + + + background-color: rgb(211,211,211); +color: rgb(0, 0, 0); + + + + + + + 120 + 120 + 71 + 31 + + + + background-color: rgb(211,211,211); +color: rgb(0, 0, 0); + + + + + + + 20 + 120 + 61 + 31 + + + + 键齿数量: + + + + + + + + diff --git a/ChaosDataPlayer/WebForm.ui b/ChaosDataPlayer/WebForm.ui new file mode 100644 index 0000000..63cc133 --- /dev/null +++ b/ChaosDataPlayer/WebForm.ui @@ -0,0 +1,78 @@ + + + WebForm + + + + 0 + 0 + 953 + 508 + + + + Form + + + #lineEdit{color: rgb(0, 0, 0);} + + + + + 2 + + + 2 + + + 2 + + + 2 + + + 2 + + + + + + + <- + + + + + + + -> + + + + + + + 刷新 + + + + + + + + + + 加载 + + + + + + + + + + + + + diff --git a/ChaosDataPlayer/WordOperate.cpp b/ChaosDataPlayer/WordOperate.cpp new file mode 100644 index 0000000..3d38a7c --- /dev/null +++ b/ChaosDataPlayer/WordOperate.cpp @@ -0,0 +1,539 @@ +/******************************************************************** + @date: 2017-11-20 + @author: gongwei@vishee.com + @edit_by: + @brief: word通用操作类 +*********************************************************************/ + +#include "WordOperate.h" +#include "qt_windows.h" + +WordOperate::WordOperate(QObject *parent):QObject(parent), + m_bOpened(false), + m_wordDocuments(NULL), + m_wordWidget(NULL), + m_selection(NULL) +{ + +} + +WordOperate::WordOperate(const QString &strFile, QObject *parent):QObject(parent), + m_bOpened(false), + m_wordDocuments(NULL), + m_wordWidget(NULL), + m_selection(NULL), + m_strFilePath(strFile) +{ + +} + + +WordOperate::~WordOperate() +{ + close(); +} + + +/****************************************************************************** + * 函数:open + * 功能:打开文件 + * 参数:bVisable 是否显示弹窗 + * 返回值: bool + *****************************************************************************/ +bool WordOperate::open(bool bVisable) +{ + //新建一个word应用程序,并设置为可见 + m_wordWidget = new QAxObject(); + bool bFlag = m_wordWidget->setControl( "word.Application" ); +// bool bFlag = false;//使用wps打开报告 + if(!bFlag) + { + // 用wps打开 + bFlag = m_wordWidget->setControl( "kwps.Application" ); + if(!bFlag) + { + return false; + } + } + m_wordWidget->setProperty("Visible", false); + //获取所有的工作文档 + QAxObject *document = m_wordWidget->querySubObject("Documents"); + if(!document) + { + return false; + } + //以文件template.dot为模版新建一个文档 + document->dynamicCall("Add(QString)", m_strFilePath); + //获取当前激活的文档 + m_wordDocuments = m_wordWidget->querySubObject("ActiveDocument"); + m_selection = m_wordWidget->querySubObject("Selection"); + m_selection->dynamicCall("InsertAfter(QString&)", "\n"); + m_bOpened = true; + return m_bOpened; +} + +/****************************************************************************** + * 函数:open + * 功能:打开文件 + * 参数:strFilePath 文件路径;bVisable 是否显示弹窗 + * 返回值:bool + *****************************************************************************/ +bool WordOperate::open(const QString& strFilePath, bool bVisable) +{ + m_strFilePath = strFilePath; + close(); + return open(bVisable); +} + +/****************************************************************************** + * 函数:close + * 功能:关闭文件 + * 参数:无 + * 返回值:bool + *****************************************************************************/ +bool WordOperate::close() +{ + if (m_bOpened) + { + m_wordDocuments->dynamicCall("Close (bool)", false); + m_wordWidget->dynamicCall("Quit()"); + m_bOpened = false; + delete m_wordWidget; + m_wordWidget = NULL; + } + + return m_bOpened; +} + +/****************************************************************************** + * 函数:isOpen + * 功能:获得当前的打开状态 + * 参数:无 + * 返回值:bool + *****************************************************************************/ +bool WordOperate::isOpen() +{ + return m_bOpened; +} + +/****************************************************************************** + * 函数:save + * 功能:保存文件 + * 参数:无 + * 返回值:void + *****************************************************************************/ +void WordOperate::save() +{ + m_wordDocuments->dynamicCall("Save()"); +} + + +/******************************************************************** + description: 打印当前文档 + 返 回 值: + 参 数: +********************************************************************/ +void WordOperate::Print() +{ + m_wordDocuments->dynamicCall("PrintOut()"); +} + + +void WordOperate::Print(int nPageFrom,int nPageTo) +{ + QList vars; + vars.push_back(QVariant(true));//background + vars.push_back(QVariant(false));//append + vars.push_back(QVariant("wdPrintRangeOfPages"));//range + vars.push_back(QVariant(""));//OutputFileName + vars.push_back(QVariant(nPageFrom));//From + vars.push_back(QVariant(nPageTo));//To + vars.push_back(QVariant("_wdPrintDocumentContent"));//Item + vars.push_back(QVariant(1));//Copy + vars.push_back(QVariant("1"));//Pages + vars.push_back(QVariant("_wdPrintAllPages"));//PageType + vars.push_back(QVariant(false));//PrintToFile + vars.push_back(QVariant(true));//Collate + vars.push_back(QVariant(""));//FileName + vars.push_back(QVariant(false));//ManualDuplexPrint + vars.push_back(QVariant(0));//PrintZoomCulumn + vars.push_back(QVariant(0));//PrintZoomRow + vars.push_back(QVariant(0));//PrintZoomPaperWidth + vars.push_back(QVariant(0));//PrintZoomPaperHeight + m_wordDocuments->dynamicCall("PrintOut(bool,bool,const QString&,const QString&,int,int,const QString&,int,const QString&,const QString&,bool,bool,const QString&,bool,int,int,int,int)",vars); +} + + +/****************************************************************************** + * 函数:saveAs + * 功能:另存文件 + * 参数:strSaveFile 文件路径 + * 返回值:void + *****************************************************************************/ +bool WordOperate::saveAs(const QString& strSaveFile) +{ + return m_wordDocuments->dynamicCall("SaveAs (const QString&)", + strSaveFile).toBool(); +} + + +/****************************************************************************** + * 函数:intsertTable + * 功能:创建表格 + * 参数:row hang; column 列 + * 返回值: void + *****************************************************************************/ +void WordOperate::intsertTable(int row, int column) +{ + + m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter"); + //selection->dynamicCall("TypeText(QString&)", "Table Test");//设置标题 + + QAxObject *range = m_selection->querySubObject("Range"); + QAxObject *tables = m_wordDocuments->querySubObject("Tables"); + QAxObject *table = tables->querySubObject("Add(QVariant,int,int)",range->asVariant(),row,column); + + for(int i=1;i<=6;i++) + { + QString str = QString("Borders(-%1)").arg(i); + QAxObject *borders = table->querySubObject(str.toLatin1().data()); + borders->dynamicCall("SetLineStyle(int)",1); + } +} + + + +/****************************************************************************** + * 函数:setCellString + * 功能:设置表格内容 + * 参数:nTable 表格; row 行数; column 列数; text 插入文本 + * 返回值:void + *****************************************************************************/ +QAxObject* WordOperate::setCellString(int nTable, int row, int column, const QString& text) +{ + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + if(table) + { + + table->querySubObject("Cell(int, int)", row, column) + ->querySubObject("Range") + ->dynamicCall("SetText(QString)", text); + return table->querySubObject("Cell(int, int)", row, column); + } +} + + + +/****************************************************************************** + * 函数:insertCellPic + * 功能:在表格中插入图片 + * 参数:nTable 表格; row 插入行; column 列数; picPath 图片路径 + * 返回值:void + *****************************************************************************/ +void WordOperate::insertCellPic(int nTable, int row, int column, + const QString& picPath) +{ + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + QAxObject* range = table->querySubObject("Cell(int, int)", row, column) + ->querySubObject("Range"); + range->querySubObject("InlineShapes") + ->dynamicCall("AddPicture(const QString&,QVariant&)",picPath,"False"); +} + +void WordOperate::SetMarkPic(QString sLabel, QString sFile) +{ + + QAxObject*bookmark_pic=m_wordDocuments->querySubObject("Bookmarks(QVariant)","pic"); + + if(!bookmark_pic->isNull()) + { + bookmark_pic->dynamicCall("Select(void)"); + + QAxObject *range; + range = bookmark_pic->querySubObject("Range"); + QVariant tmp = range->asVariant(); + QListqList; + qList<querySubObject("InlineShapes"); + Inlineshapes->dynamicCall("AddPicture(const QString&, QVariant, QVariant ,QVariant)",qList); + } + +} +/******************************************************************** + description: 合并单元格 + 返 回 值: nTable 表格索引,从1开始 + nStartRow合并起始行,从1开始,nStartCol合并起始列,从1开始 + nEndRow合并终止行,nEndCol合并终止列 + 参 数: +********************************************************************/ +void WordOperate::MergeCell(int nTable, int nStartRow, int nStartCol, int nEndRow, int nEndCol,bool bVerticalCenter) +{ + QAxObject* tables = m_wordDocuments->querySubObject("Tables"); + QAxObject* table = tables->querySubObject("Item(int)",nTable); + QAxObject* StartCell =table->querySubObject("Cell(int, int)",nStartRow,nStartCol); + QAxObject* EndCell = table->querySubObject("Cell(int, int)",nEndRow,nEndCol); + StartCell->querySubObject("Merge(QAxObject *)",EndCell->asVariant()); + //设置对齐方式 -上下对齐 + if(bVerticalCenter) + StartCell->dynamicCall("VerticalAlignment", "wdCellAlignVerticalCenter"); + else + { + m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphJustify"); + StartCell->dynamicCall("VerticalAlignment", "wdCellAlignVerticalTop"); + } + +} + + +/******************************************************************** + description: 拆分单元格 + 返 回 值: + 参 数: nTable 表格索引,从1开始,nStartRow行号,从1开始,nStartCol列号,从1开始 + nRow为要拆分的行数,nCol为要拆分的列数 +********************************************************************/ +void WordOperate::SplitCell(int nTable, int nStartRow, int nStartCol, int nRow, int nCol) +{ + QAxObject* tables = m_wordDocuments->querySubObject("Tables"); + QAxObject* table = tables->querySubObject("Item(int)",nTable); + QAxObject* StartCell =table->querySubObject("Cell(int, int)",nStartRow,nStartCol); + StartCell->querySubObject("Split(int,int)",nRow,nCol); +} + +/******************************************************************** + description: 设置对齐方式 + 返 回 值: nAlign对齐方式 0-左对齐 1居中 2右对齐 + 参 数: +********************************************************************/ +void WordOperate::SetAlign(AlignmentType nAlign) +{ + switch(nAlign) + { + case 0: + m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphLeft"); + break; + case 1: + m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphCenter"); + break; + case 2: + m_selection->querySubObject("ParagraphFormat")->dynamicCall("Alignment", "wdAlignParagraphRight"); + break; + } + + +} + +void WordOperate::SetTableFont(QAxObject* cell, QString strFamily, int nSize, bool bBold, bool bItalic) +{ + QAxObject *font = cell->querySubObject("Select"); + m_selection->querySubObject("Font")->setProperty("Name", strFamily); + m_selection->querySubObject("Font")->setProperty("Size", nSize); + m_selection->querySubObject("Font")->setProperty("Bold", bBold); + m_selection->querySubObject("Font")->setProperty("Italic", bItalic); + m_selection->dynamicCall("MoveRight(const QString&,int)", "wdCharacter",1); +} +/******************************************************************** + description: 设置Table cell字体 + 返 回 值: + 参 数: nTable 表格编号 + row 行号 + column 列号 + strFamily 字体名称 + nSize 字号 + bBold 加粗 + bItalic 斜体 + bool 下划线 +********************************************************************/ +void WordOperate::SetTableFont(int nTable,int row,int column,QString strFamily,int nSize,bool bBold ,bool bItalic,bool bUnderLine) +{ + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + if(table) + { + QAxObject* range = table->querySubObject("Cell(int, int)", row, column) + ->querySubObject("Range"); + range->querySubObject("Font") + ->setProperty("Name", strFamily); + range->querySubObject("Font")->setProperty("Size", nSize); + range->querySubObject("Font")->setProperty("Bold", bBold); + range->querySubObject("Font")->setProperty("Italic", bItalic); + if(bUnderLine) + range->querySubObject("Font")->setProperty("Underline",2); + else + range->querySubObject("Font")->setProperty("Underline",0); + //为Table的一行设置字体 +// QAxObject* rowRange = table->querySubObject("Rows(int)",row)->querySubObject("Select"); +// m_selection->querySubObject("Font")->setProperty("Name", strFamily); +// m_selection->querySubObject("Font")->setProperty("Size", nSize); +// m_selection->querySubObject("Font")->setProperty("Bold", bBold); +// m_selection->querySubObject("Font")->setProperty("Italic", bItalic); + } +} + +/******************************************************************** + description: 设置字体 + 返 回 值: strFamily 字体,nSize 字号,bBold 粗体,bItalic 斜体 + 参 数: +********************************************************************/ +void WordOperate::SetFont(QString strFamily, int nSize, bool bBold, bool bItalic,bool bUnderLine) +{ + m_selection->querySubObject("Font")->setProperty("Name", strFamily); + m_selection->querySubObject("Font")->setProperty("Size", nSize); + m_selection->querySubObject("Font")->setProperty("Bold", bBold); + m_selection->querySubObject("Font")->setProperty("Italic", bItalic); + if(bUnderLine) + m_selection->querySubObject("Font")->setProperty("Underline",2); + else + m_selection->querySubObject("Font")->setProperty("Underline",0); +} + +void WordOperate::InsertPicture(QString picturePath) +{ + m_selection->querySubObject("InlineShapes")->dynamicCall("AddPicture(const QString&)",picturePath); +} + +void WordOperate::moveForEnd()//光标移到末尾 +{ + QAxObject* selection = m_wordWidget->querySubObject("Selection"); + QVariantList params; + params.append(6); + params.append(0); + selection->dynamicCall("EndOf(QVariant&, QVariant&)", params).toInt(); +} +void WordOperate::insertEnter() +{ + QAxObject* selection = m_wordWidget->querySubObject("Selection"); + selection->dynamicCall("TypeParagraph(void)"); +} +void WordOperate::moveRight() +{ + QAxObject* selection = m_wordWidget->querySubObject("Selection"); + selection->dynamicCall("MoveRight(int)",1); +} +void WordOperate::SetText(QString strText) +{ + m_selection->dynamicCall("TypeText(QString&)", strText); +} + + +void WordOperate::GetPageMargin(double &dbLeft, double &dbTop, double &dbRight, double &dbBottom) +{ + QAxObject* pageSetup = m_selection->querySubObject("PageSetup"); + dbLeft = pageSetup->property("LeftMargin").toDouble(); + dbTop = pageSetup->property("TopMargin").toDouble(); + dbRight = pageSetup->property("RightMargin").toDouble(); + dbBottom = pageSetup->property("BottomMargin").toDouble(); +} +void WordOperate::SetVisible(bool bVisable) +{ + m_wordWidget->setProperty("Visible", bVisable); +} + +void WordOperate::SetPageMargin(double dbLeft, double dbTop, double dbRight, double dbBottom) +{ + QAxObject* pageSetup = m_selection->querySubObject("PageSetup"); + pageSetup->setProperty("LeftMargin",dbLeft); + pageSetup->setProperty("RightMargin",dbRight); + pageSetup->setProperty("TopMargin",dbTop); + pageSetup->setProperty("BottomMargin",dbBottom); +} + +bool WordOperate::SetTableRowHeight(int nTable,int row,int height) +{ + bool flag=false; + + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + if(table) + { + QAxObject* cell =table->querySubObject("Cell(int, int)",row,1); + flag = cell->setProperty("HeightRule", "wdRowHeightExactly");//wdRowHeightAtLeast wdRowHeightExactly wdRowHeightAuto + + if(cell) + flag = cell->setProperty("Height", height); + } + return flag; +} + +void WordOperate::SetParagraphSpacing(SpaceType type,int space) +{ + QAxObject* para = m_selection->querySubObject("ParagraphFormat"); + switch (type) { + case Space1: + para->setProperty("LineSpacingRule","wdLineSpaceSingle"); + break; + case Space15: + para->setProperty("LineSpacingRule","wdLineSpace1pt5"); + break; + case Space2: + para->setProperty("LineSpacingRule","wdLineSpaceDouble"); + break; + case SpaceAtLeast: + para->setProperty("LineSpacingRule","wdLineSpaceAtLeast"); + para->setProperty("LineSpacing",space); + break; + case SpaceExactly: + para->setProperty("LineSpacingRule","wdLineSpaceExactly"); + para->setProperty("LineSpacing",space); + break; + case SpaceMuti: + para->setProperty("LineSpacingRule","wdLineSpaceMultiple"); + para->setProperty("LineSpacing",space); + break; + default: + break; + } + +} + +void WordOperate::SetColumnWidth(int nTable, int column, int width) +{ + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + if(table) + { + QAxObject* colum = table->querySubObject("Columns(int)",column); + if(colum) + colum->setProperty("Width",width); + } +} + +void WordOperate::HideBorder(int nTable, int row, int column, int item) +{ + QAxObject* pTables = m_wordDocuments->querySubObject( "Tables" ); + QAxObject* table = pTables->querySubObject("Item(int)", nTable); + QAxObject* cell =table->querySubObject("Cell(int, int)",row,column); + QAxObject* border = cell->querySubObject("Borders(int)",item); + if(border) + border->setProperty("Visible",false); +/* + QAxObject* Borders = table->querySubObject("Borders"); + Borders->setProperty("InsideLineStyle",1); + Borders->setProperty("OutsideLineStyle",1); +*/ +} + + +void WordOperate::AddTableRow(int tableIndex ,int nRow,int rowCount) +{ + QAxObject* tables=m_wordDocuments->querySubObject("Tables"); + QAxObject* table = tables->querySubObject("Item(int)",tableIndex); + QAxObject* rows =table->querySubObject("Rows"); + int Count =rows->dynamicCall("Count").toInt(); + if(0< nRow && nRow <= Count ) + { + for(int i =0; i< rowCount; ++i) + { + QString sPos = QString("Item(%1)").arg(nRow+i); + QAxObject* row= rows->querySubObject(sPos.toStdString().c_str()); + QVariant param =row ->asVariant(); + rows->dynamicCall("Add(Variant)",param); + } + } +} + diff --git a/ChaosDataPlayer/WordOperate.h b/ChaosDataPlayer/WordOperate.h new file mode 100644 index 0000000..22e5ef9 --- /dev/null +++ b/ChaosDataPlayer/WordOperate.h @@ -0,0 +1,112 @@ +/******************************************************************** + @date: 2017-11-20 + @author: gongwei@vishee.com + @edit_by: + @brief: 通用的word操作类,报告创建一个word,保存,打印,表格操作,字体操作 + 注意:表格中的索引均是从1开始 +*********************************************************************/ + +#ifndef WORDOPERATE_H +#define WORDOPERATE_H + +#include +#include +#include +#include +#include +#include +class WordOperate : public QObject +{ + Q_OBJECT + +public: + enum AlignmentType{ + AlignmentTypeLeft, + AlignmentTypeCenter, + AlignmentTypeRight + + }; + + enum SpaceType// + { + Space1, + Space15, + Space2, + SpaceAtLeast, + SpaceExactly, + SpaceMuti + }; + + explicit WordOperate(QObject *parent = 0); + WordOperate(const QString& strFile, QObject *parent = 0); + ~WordOperate(); + + bool open(bool bVisable = false); + bool open(const QString& strFile, bool bVisable = true); + bool close(); + bool isOpen(); + void save(); + bool saveAs(const QString& strSaveFile); + // 创建表格 + void intsertTable(int row, int column); + // 设置表格内容 + QAxObject* setCellString(int nTable, int row, int column, const QString& text); + // 合并单元格 + void MergeCell(int nTable,int nStartRow,int nStartCol,int nEndRow,int nEndCol,bool bVerticalCenter = false ); + //拆分单元格 + void SplitCell(int nTable,int nStartRow,int nStartCol,int nRow,int nCol); + // 在表格中插入图片 + void insertCellPic(int nTable, int row,int column,const QString& picPath); + //光标跳转,类似于表格中的tab + void moveRight(); + void SetMarkPic(QString sLabel, QString sFile); + // 设置文字 + void SetFont(QString strFamily,int nSize,bool bBold = false,bool bItalic = false,bool bUnderLine = false); + // 设置表格文字字体 + void SetTableFont(QAxObject* cell,QString strFamily,int nSize,bool bBold = false,bool bItalic = false); + // 设置表格文字字体 + void SetTableFont(int nTable,int row,int column,QString strFamily,int nSize,bool bBold = false,bool bItalic = false,bool bUnderLine=false); + // 设置对其方式 + void SetAlign(AlignmentType nAlign); + // 打印当期前document + void Print(); + void Print(int nPageFrom,int nPageTo); + //光标移到末尾 + void moveForEnd(); + //回车 + void insertEnter(); + //插入图片 + void InsertPicture(QString picturePath); + //插入文字 + void SetText(QString strText); + //获取页边距 + void GetPageMargin(double &dbLeft,double &dbTop,double &dbRight,double &dbBottom); + //设置页边距 + void SetPageMargin(double dbLeft,double dbTop,double dbRight,double dbBottom); + //设置文档可见 + void SetVisible(bool bVisable = true); + //设置表格行高 + bool SetTableRowHeight(int nTable,int row,int height); + //设置段落行间距 + void SetParagraphSpacing(SpaceType type,int space=0); + //设置列宽 + void SetColumnWidth(int nTable, int column, int width); + //隐藏表格边框 + void HideBorder(int nTable,int row,int column,int item); + //增加table行 + void AddTableRow(int tableIndex ,int nRow,int rowCount); +public: + QAxObject *m_wordDocuments; + QAxObject *m_wordWidget; + QAxObject *m_selection; +private: + bool m_bOpened; + QString m_strFilePath; + + +signals: + +public slots: +}; + +#endif // WORDOPERATE_H diff --git a/ChaosDataPlayer/cidwudp.cpp b/ChaosDataPlayer/cidwudp.cpp new file mode 100644 index 0000000..4a43ffb --- /dev/null +++ b/ChaosDataPlayer/cidwudp.cpp @@ -0,0 +1,54 @@ +#include "cidwudp.h" +#include +#include +#include + +QString DeviceNO; + +CIDWUdp::CIDWUdp(QObject *parent): + QObject(parent) +{ + Init(); +} + +CIDWUdp::~CIDWUdp() +{ + +} + +void CIDWUdp::Init() +{ + m_pUdpSocket = new QUdpSocket(this); + m_pUdpSocket->bind(QHostAddress::Any,7302); //绑定端口号 + bool udpflag = connect(m_pUdpSocket, SIGNAL(readyRead()), //连接信号槽函数 + this, SLOT(ReadPendingDatagrams())); + qDebug()<<"CIDWUdp::Init()::::::::"<hasPendingDatagrams()) + { + QByteArray datagram; + datagram.resize(m_pUdpSocket->pendingDatagramSize()); + qint64 iRet = m_pUdpSocket->readDatagram(datagram.data(), datagram.size(),&m_targetaddr, &m_targetport); + qDebug()<<"CIDWUdp::ReadPendingDatagrams()++++++++" << datagram.data() << "size" << iRet; + qDebug()<<"CIDWUdp::ReadPendingDatagrams()========" << m_targetaddr.toString().mid(7); + if(AddFlag == false) + { + emit IpSignal(m_targetaddr.toString().mid(7)); + } + + UserOnlineInfo(datagram,m_targetaddr.toString().mid(7)); + } +} diff --git a/ChaosDataPlayer/cidwudp.h b/ChaosDataPlayer/cidwudp.h new file mode 100644 index 0000000..ed84e0f --- /dev/null +++ b/ChaosDataPlayer/cidwudp.h @@ -0,0 +1,30 @@ +#ifndef CIDWUDP_H +#define CIDWUDP_H + +#include +#include +#include +#include +#include "global.h" + +class CIDWUdp:public QObject +{ + Q_OBJECT +public: + explicit CIDWUdp(QObject *parent = 0); + ~CIDWUdp(); + void Init(); + void UserOnlineInfo(QByteArray datagram,QString strIP); +private slots: + void ReadPendingDatagrams(); +signals: + void RetSignal(QString,QString strIP); + void IpSignal(QString); + +private: + QUdpSocket *m_pUdpSocket; + QHostAddress m_targetaddr;//ip + quint16 m_targetport;//端口号 +}; + +#endif // CIDWUDP_H diff --git a/ChaosDataPlayer/fftw3.h b/ChaosDataPlayer/fftw3.h new file mode 100644 index 0000000..39661d2 --- /dev/null +++ b/ChaosDataPlayer/fftw3.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http://www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) +#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) + +/* IMPORTANT: for Windows compilers, you should add a line +*/ +#define FFTW_DLL +/* + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllimport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +#include /* for ptrdiff_t */ +struct fftw_iodim64_do_not_use_me { + ptrdiff_t n; /* dimension size */ + ptrdiff_t is; /* input stride */ + ptrdiff_t os; /* output stride */ +}; + +typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); +typedef int (*fftw_read_char_func_do_not_use_me)(void *); + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ +typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ +typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ + \ +FFTW_EXTERN void X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ +FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ + R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ + int n2, \ + R *in, C *out, unsigned flags); \ + \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ + C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ + int n2, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ +FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ +FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ + X(r2r_kind) kind0, X(r2r_kind) kind1, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ + R *in, R *out, X(r2r_kind) kind0, \ + X(r2r_kind) kind1, X(r2r_kind) kind2, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ +FFTW_EXTERN void X(forget_wisdom)(void); \ +FFTW_EXTERN void X(cleanup)(void); \ + \ +FFTW_EXTERN void X(set_timelimit)(double t); \ + \ +FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ +FFTW_EXTERN int X(init_threads)(void); \ +FFTW_EXTERN void X(cleanup_threads)(void); \ +FFTW_EXTERN void X(make_planner_thread_safe)(void); \ + \ +FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ +FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ +FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ +FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ + void *data); \ +FFTW_EXTERN int X(import_system_wisdom)(void); \ +FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ +FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ +FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ +FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ + \ +FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ +FFTW_EXTERN void X(print_plan)(const X(plan) p); \ +FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void *X(malloc)(size_t n); \ +FFTW_EXTERN R *X(alloc_real)(size_t n); \ +FFTW_EXTERN C *X(alloc_complex)(size_t n); \ +FFTW_EXTERN void X(free)(void *p); \ + \ +FFTW_EXTERN void X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ +FFTW_EXTERN double X(cost)(const X(plan) p); \ + \ +FFTW_EXTERN int X(alignment_of)(R *p); \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 + for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ + && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ + && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) +# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +/* note: __float128 is a typedef, which is not supported with the _Complex + keyword in gcc, so instead we use this ugly __attribute__ version. + However, we can't simply pass the __attribute__ version to + FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer + types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ +# undef FFTW_DEFINE_COMPLEX +# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C +# endif +FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +#endif + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) +#define FFTW_WISDOM_ONLY (1U << 21) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/ChaosDataPlayer/fftwlib/fftw3.h b/ChaosDataPlayer/fftwlib/fftw3.h new file mode 100644 index 0000000..39661d2 --- /dev/null +++ b/ChaosDataPlayer/fftwlib/fftw3.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2003, 2007-14 Matteo Frigo + * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http://www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) +#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name) + +/* IMPORTANT: for Windows compilers, you should add a line +*/ +#define FFTW_DLL +/* + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllimport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +#include /* for ptrdiff_t */ +struct fftw_iodim64_do_not_use_me { + ptrdiff_t n; /* dimension size */ + ptrdiff_t is; /* input stride */ + ptrdiff_t os; /* output stride */ +}; + +typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *); +typedef int (*fftw_read_char_func_do_not_use_me)(void *); + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ +typedef struct fftw_iodim64_do_not_use_me X(iodim64); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +typedef fftw_write_char_func_do_not_use_me X(write_char_func); \ +typedef fftw_read_char_func_do_not_use_me X(read_char_func); \ + \ +FFTW_EXTERN void X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ +FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \ + R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \ + int n2, \ + R *in, C *out, unsigned flags); \ + \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \ + C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \ + int n2, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \ + const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \ + int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ +FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ +FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \ + X(r2r_kind) kind0, X(r2r_kind) kind1, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \ + R *in, R *out, X(r2r_kind) kind0, \ + X(r2r_kind) kind1, X(r2r_kind) kind2, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \ + int howmany_rank, \ + const X(iodim64) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ +FFTW_EXTERN void X(forget_wisdom)(void); \ +FFTW_EXTERN void X(cleanup)(void); \ + \ +FFTW_EXTERN void X(set_timelimit)(double t); \ + \ +FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ +FFTW_EXTERN int X(init_threads)(void); \ +FFTW_EXTERN void X(cleanup_threads)(void); \ +FFTW_EXTERN void X(make_planner_thread_safe)(void); \ + \ +FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \ +FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ +FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ +FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \ + void *data); \ +FFTW_EXTERN int X(import_system_wisdom)(void); \ +FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \ +FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ +FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ +FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \ + \ +FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ +FFTW_EXTERN void X(print_plan)(const X(plan) p); \ +FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void *X(malloc)(size_t n); \ +FFTW_EXTERN R *X(alloc_real)(size_t n); \ +FFTW_EXTERN C *X(alloc_complex)(size_t n); \ +FFTW_EXTERN void X(free)(void *p); \ + \ +FFTW_EXTERN void X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ +FFTW_EXTERN double X(cost)(const X(plan) p); \ + \ +FFTW_EXTERN int X(alignment_of)(R *p); \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64 + for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */ +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \ + && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \ + && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__)) +# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +/* note: __float128 is a typedef, which is not supported with the _Complex + keyword in gcc, so instead we use this ugly __attribute__ version. + However, we can't simply pass the __attribute__ version to + FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer + types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */ +# undef FFTW_DEFINE_COMPLEX +# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C +# endif +FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex) +#endif + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) +#define FFTW_WISDOM_ONLY (1U << 21) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/ChaosDataPlayer/fftwlib/libfftw3-3.dll b/ChaosDataPlayer/fftwlib/libfftw3-3.dll new file mode 100644 index 0000000..f5a97b4 Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3-3.dll differ diff --git a/ChaosDataPlayer/fftwlib/libfftw3-3.lib b/ChaosDataPlayer/fftwlib/libfftw3-3.lib new file mode 100644 index 0000000..c6d07e4 Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3-3.lib differ diff --git a/ChaosDataPlayer/fftwlib/libfftw3f-3.dll b/ChaosDataPlayer/fftwlib/libfftw3f-3.dll new file mode 100644 index 0000000..b0a053a Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3f-3.dll differ diff --git a/ChaosDataPlayer/fftwlib/libfftw3f-3.lib b/ChaosDataPlayer/fftwlib/libfftw3f-3.lib new file mode 100644 index 0000000..ce839b0 Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3f-3.lib differ diff --git a/ChaosDataPlayer/fftwlib/libfftw3l-3.dll b/ChaosDataPlayer/fftwlib/libfftw3l-3.dll new file mode 100644 index 0000000..abc81ea Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3l-3.dll differ diff --git a/ChaosDataPlayer/fftwlib/libfftw3l-3.lib b/ChaosDataPlayer/fftwlib/libfftw3l-3.lib new file mode 100644 index 0000000..1a9c8e8 Binary files /dev/null and b/ChaosDataPlayer/fftwlib/libfftw3l-3.lib differ diff --git a/ChaosDataPlayer/global.cpp b/ChaosDataPlayer/global.cpp new file mode 100644 index 0000000..d59bca4 --- /dev/null +++ b/ChaosDataPlayer/global.cpp @@ -0,0 +1,31 @@ +#include "global.h" +#include +#include +quint16 global::port = 1883; +QString global::IpAddr_G = ""; +QString global::MacAddr_G = ""; +QString global::FilePath_G = ""; +//QString global::m_nowName = ""; +int global::m_nowChannel = 0; +int global::Count_G = 0; +RotatingSpeed global::rotatingSpeed; + +QVector global::m_featureData = QVector(); + + +void global::Sleep(int msec) +{ + QTime dieTime = QTime::currentTime().addMSecs(msec); + while( QTime::currentTime() < dieTime ) + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); +} + +global::global() +{ + +} + +global::~global() +{ + +} diff --git a/ChaosDataPlayer/global.h b/ChaosDataPlayer/global.h new file mode 100644 index 0000000..199b73b --- /dev/null +++ b/ChaosDataPlayer/global.h @@ -0,0 +1,192 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +#include +#include +#include +#include +#include "qmap.h" + +#define SAVE_SPEEDTIME //存储转速时间戳 +enum Except{ EXCEP_ZERO,EXCEP_ONE}; +extern bool AddFlag; +extern QString DeviceNO; +typedef struct tag_WAVE_DATA{ + QString channelId; + QString channelName; + int wavesize; + int SamleRate; + int SamleRateRealTime; + float mean; + QString sensorType; + int channelNo; + int Time; + QString pairChannelID; + QVector waveData; + QVector waveDataRealTime; + QColor linColor; + QVector SpeedProfileSpeed; + QString sensorEngineeringUnit; + QString speedRefChannelId; + double sensorGapVoltage; + double sensorSensitivity; + int iTrigger; + int iKeyCount; + float iTriggerValue; + float iHysteresis; + bool tachAutoTach; + QVector TimeStamp; + QVector RMSValue; + tag_WAVE_DATA(){ + channelId = ""; + channelName = ""; + wavesize = 0; + SamleRate = 0; + mean = 0.0; + sensorType = ""; + channelNo = 0; + Time = 0; + pairChannelID = ""; + sensorEngineeringUnit = ""; + speedRefChannelId = ""; + iTrigger = -1; + iKeyCount= 0; + iTriggerValue = 0.0; + iHysteresis = 0.0; + } +} WAVE_DATA; +typedef struct { + QString channelId; + float wavedata; +} WAVE_ALLDATA; + +typedef struct { + int Second; + QString channelId; + QVector waveData; + QVector TimeStamp; +} WAVE_CHNDATA; + +//实时数据 +typedef struct { + int total; + int count; + int type; // 1: 转速通道 0:其他 + int number; // 原始数据量 + int flag; // 平台标识 + char channelId[16]; + char SensorEngineeringUnit[32]; + float waveData[32768]; +} WAVE_CONTAIN; + +typedef struct { + QString channelId; + QVector wavedata; +} WAVE_CSVDATA; + +typedef struct { + QVector Key; + QVector wavedata; //原始数据 + QVector wavedataEnv;//包络数据 + QVector wavedata_DC; + QVector TimeStamp; + QColor linColor; + QString channelType; + QString sensorEngineeringUnit; + int SamleRate; + float mean; + double meanRpm; + QString channleName; + int iTrigger; + int iKeyCount; + float iTriggerValue; + float iHysteresis; + bool tachAutoTach; +} WAVE_DISPALYDATA; + +typedef struct{ + QString channelId; + QString channelType; + QString channelName; + int channelSamleRate; + QString sensorType; + QString pairChannelID; + QString equipmentName; + int TachTriggerPerRev; + QString sensorEngineeringUnit; + QString speedRefChannelId; + bool tachAutoTach; + QVector SpeedProfileSpeed; + QVector RMSValue; + double sensorGapVoltage; + double sensorSensitivity; + int iTrigger; + int iKeyCount; + int iTriggerValue; + int iHysteresis; +}WAVE_INFO; + +typedef struct tag_DEVICE_INFO{ + QString DeviceMac; + QString DeviceName; + QString DeviceIP; + QString DeviceType; + tag_DEVICE_INFO(){ + DeviceMac = ""; + DeviceName = ""; + DeviceIP = ""; + DeviceType = ""; + } +}DEVICE_INFO; + + +typedef struct tag_REPORT_INFO{ + QString DeviceMac; + QString DeviceName; + QString DevicemCollectTime; + + tag_REPORT_INFO(){ + DeviceMac = ""; + DeviceName = ""; + DevicemCollectTime = ""; + } +}REPORT_INFO; + +typedef struct { + QVector key; + QVector value; +} KeyPhasor; + + + +typedef struct tag_RotatingSpeed{ + int iTrigger; + int iTriggerValue; + int iKeyCount; + int iHysteresis; + tag_RotatingSpeed(){ + iTrigger = -1; + iTriggerValue = 0; + iKeyCount = 0; + iHysteresis = 0; + } +}RotatingSpeed ; + +class global +{ +public: + global(); + ~global(); + void Sleep(int msec); +public: + static quint16 port; + static QString IpAddr_G; //设备IP + static QString MacAddr_G; //设备MAC地址 + static QString FilePath_G; //文件路径 + static int m_nowChannel; //当前通道 + static int Count_G; //dat文件总共秒数 + static QVector m_featureData; + static RotatingSpeed rotatingSpeed; +}; + +#endif // GLOBAL_H diff --git a/ChaosDataPlayer/images/bg_main.png b/ChaosDataPlayer/images/bg_main.png new file mode 100644 index 0000000..b69fd3d Binary files /dev/null and b/ChaosDataPlayer/images/bg_main.png differ diff --git a/ChaosDataPlayer/images/bg_top.png b/ChaosDataPlayer/images/bg_top.png new file mode 100644 index 0000000..1ee9093 Binary files /dev/null and b/ChaosDataPlayer/images/bg_top.png differ diff --git a/ChaosDataPlayer/images/checkbox/_desktop.ini b/ChaosDataPlayer/images/checkbox/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/checkbox/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/checkbox/checked.png b/ChaosDataPlayer/images/checkbox/checked.png new file mode 100644 index 0000000..0a42016 Binary files /dev/null and b/ChaosDataPlayer/images/checkbox/checked.png differ diff --git a/ChaosDataPlayer/images/checkbox/partchecked.png b/ChaosDataPlayer/images/checkbox/partchecked.png new file mode 100644 index 0000000..31a1fac Binary files /dev/null and b/ChaosDataPlayer/images/checkbox/partchecked.png differ diff --git a/ChaosDataPlayer/images/checkbox/uncheck.png b/ChaosDataPlayer/images/checkbox/uncheck.png new file mode 100644 index 0000000..9c9a0a9 Binary files /dev/null and b/ChaosDataPlayer/images/checkbox/uncheck.png differ diff --git a/ChaosDataPlayer/images/close_h.png b/ChaosDataPlayer/images/close_h.png new file mode 100644 index 0000000..89ffed6 Binary files /dev/null and b/ChaosDataPlayer/images/close_h.png differ diff --git a/ChaosDataPlayer/images/close_n.png b/ChaosDataPlayer/images/close_n.png new file mode 100644 index 0000000..b16bf3f Binary files /dev/null and b/ChaosDataPlayer/images/close_n.png differ diff --git a/ChaosDataPlayer/images/close_s.png b/ChaosDataPlayer/images/close_s.png new file mode 100644 index 0000000..2b43366 Binary files /dev/null and b/ChaosDataPlayer/images/close_s.png differ diff --git a/ChaosDataPlayer/images/hideChannel.png b/ChaosDataPlayer/images/hideChannel.png new file mode 100644 index 0000000..7a3e60c Binary files /dev/null and b/ChaosDataPlayer/images/hideChannel.png differ diff --git a/ChaosDataPlayer/images/hideChannel_.png b/ChaosDataPlayer/images/hideChannel_.png new file mode 100644 index 0000000..c5cd8c3 Binary files /dev/null and b/ChaosDataPlayer/images/hideChannel_.png differ diff --git a/ChaosDataPlayer/images/ico.rar b/ChaosDataPlayer/images/ico.rar new file mode 100644 index 0000000..76c9b29 Binary files /dev/null and b/ChaosDataPlayer/images/ico.rar differ diff --git a/ChaosDataPlayer/images/ico/b6.png b/ChaosDataPlayer/images/ico/b6.png new file mode 100644 index 0000000..acdab00 Binary files /dev/null and b/ChaosDataPlayer/images/ico/b6.png differ diff --git a/ChaosDataPlayer/images/ico/b7.png b/ChaosDataPlayer/images/ico/b7.png new file mode 100644 index 0000000..2c50189 Binary files /dev/null and b/ChaosDataPlayer/images/ico/b7.png differ diff --git a/ChaosDataPlayer/images/ico/ico2.rar b/ChaosDataPlayer/images/ico/ico2.rar new file mode 100644 index 0000000..bdc6c4b Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2.rar differ diff --git a/ChaosDataPlayer/images/ico/ico2/b6-h.png b/ChaosDataPlayer/images/ico/ico2/b6-h.png new file mode 100644 index 0000000..7d2c711 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/b6-h.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/b7-h.png b/ChaosDataPlayer/images/ico/ico2/b7-h.png new file mode 100644 index 0000000..950623a Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/b7-h.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/关闭-1.png b/ChaosDataPlayer/images/ico/ico2/关闭-1.png new file mode 100644 index 0000000..f8d4a24 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/关闭-1.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/关闭.png b/ChaosDataPlayer/images/ico/ico2/关闭.png new file mode 100644 index 0000000..acdab00 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/关闭.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/导出 (-1.png b/ChaosDataPlayer/images/ico/ico2/导出 (-1.png new file mode 100644 index 0000000..ff34f31 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/导出 (-1.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/导出 (1).png b/ChaosDataPlayer/images/ico/ico2/导出 (1).png new file mode 100644 index 0000000..2c50189 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/导出 (1).png differ diff --git a/ChaosDataPlayer/images/ico/ico2/导出-1.png b/ChaosDataPlayer/images/ico/ico2/导出-1.png new file mode 100644 index 0000000..186b333 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/导出-1.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/导出-2.png b/ChaosDataPlayer/images/ico/ico2/导出-2.png new file mode 100644 index 0000000..59e4b9d Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/导出-2.png differ diff --git a/ChaosDataPlayer/images/ico/ico2/导出.png b/ChaosDataPlayer/images/ico/ico2/导出.png new file mode 100644 index 0000000..3b80ce2 Binary files /dev/null and b/ChaosDataPlayer/images/ico/ico2/导出.png differ diff --git a/ChaosDataPlayer/images/ico/导出.png b/ChaosDataPlayer/images/ico/导出.png new file mode 100644 index 0000000..3b80ce2 Binary files /dev/null and b/ChaosDataPlayer/images/ico/导出.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M1-h.png b/ChaosDataPlayer/images/imgDatamodel/M1-h.png new file mode 100644 index 0000000..fe52277 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M1-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M1-p.png b/ChaosDataPlayer/images/imgDatamodel/M1-p.png new file mode 100644 index 0000000..ea8f31a Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M1-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M1.png b/ChaosDataPlayer/images/imgDatamodel/M1.png new file mode 100644 index 0000000..0312e3f Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M1.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M10-h.png b/ChaosDataPlayer/images/imgDatamodel/M10-h.png new file mode 100644 index 0000000..f111ffe Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M10-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M10-p.png b/ChaosDataPlayer/images/imgDatamodel/M10-p.png new file mode 100644 index 0000000..d6469ae Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M10-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M10.png b/ChaosDataPlayer/images/imgDatamodel/M10.png new file mode 100644 index 0000000..1a97a6b Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M10.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M11-h.png b/ChaosDataPlayer/images/imgDatamodel/M11-h.png new file mode 100644 index 0000000..72f63c7 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M11-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M11-p.png b/ChaosDataPlayer/images/imgDatamodel/M11-p.png new file mode 100644 index 0000000..3a6f2a6 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M11-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M11.png b/ChaosDataPlayer/images/imgDatamodel/M11.png new file mode 100644 index 0000000..6399536 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M11.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M12-h.png b/ChaosDataPlayer/images/imgDatamodel/M12-h.png new file mode 100644 index 0000000..f13ce63 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M12-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M12-p.png b/ChaosDataPlayer/images/imgDatamodel/M12-p.png new file mode 100644 index 0000000..98a6926 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M12-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M12.png b/ChaosDataPlayer/images/imgDatamodel/M12.png new file mode 100644 index 0000000..1704a40 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M12.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M2-h.png b/ChaosDataPlayer/images/imgDatamodel/M2-h.png new file mode 100644 index 0000000..52fef33 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M2-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M2-p.png b/ChaosDataPlayer/images/imgDatamodel/M2-p.png new file mode 100644 index 0000000..a8f461e Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M2-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M2.png b/ChaosDataPlayer/images/imgDatamodel/M2.png new file mode 100644 index 0000000..160d2b6 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M2.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M3-h.png b/ChaosDataPlayer/images/imgDatamodel/M3-h.png new file mode 100644 index 0000000..1e5cd0b Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M3-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M3-p.png b/ChaosDataPlayer/images/imgDatamodel/M3-p.png new file mode 100644 index 0000000..9d47f1e Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M3-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M3.png b/ChaosDataPlayer/images/imgDatamodel/M3.png new file mode 100644 index 0000000..dfb542f Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M3.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M4-h.png b/ChaosDataPlayer/images/imgDatamodel/M4-h.png new file mode 100644 index 0000000..289aadc Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M4-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M4-p.png b/ChaosDataPlayer/images/imgDatamodel/M4-p.png new file mode 100644 index 0000000..7bf9b41 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M4-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M4.png b/ChaosDataPlayer/images/imgDatamodel/M4.png new file mode 100644 index 0000000..f3c5d61 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M4.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M5-h.png b/ChaosDataPlayer/images/imgDatamodel/M5-h.png new file mode 100644 index 0000000..2f530ba Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M5-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M5-p.png b/ChaosDataPlayer/images/imgDatamodel/M5-p.png new file mode 100644 index 0000000..fd093f0 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M5-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M5.png b/ChaosDataPlayer/images/imgDatamodel/M5.png new file mode 100644 index 0000000..b9c62f4 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M5.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M6-h.png b/ChaosDataPlayer/images/imgDatamodel/M6-h.png new file mode 100644 index 0000000..5c7ab04 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M6-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M6-p.png b/ChaosDataPlayer/images/imgDatamodel/M6-p.png new file mode 100644 index 0000000..308b5c7 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M6-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M6.png b/ChaosDataPlayer/images/imgDatamodel/M6.png new file mode 100644 index 0000000..0ce834c Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M6.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M7-h.png b/ChaosDataPlayer/images/imgDatamodel/M7-h.png new file mode 100644 index 0000000..a8e586d Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M7-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M7-p.png b/ChaosDataPlayer/images/imgDatamodel/M7-p.png new file mode 100644 index 0000000..180b2cd Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M7-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M7.png b/ChaosDataPlayer/images/imgDatamodel/M7.png new file mode 100644 index 0000000..ef2e5fd Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M7.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M8-h.png b/ChaosDataPlayer/images/imgDatamodel/M8-h.png new file mode 100644 index 0000000..abe91f5 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M8-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M8-p.png b/ChaosDataPlayer/images/imgDatamodel/M8-p.png new file mode 100644 index 0000000..5a578f8 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M8-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M8.png b/ChaosDataPlayer/images/imgDatamodel/M8.png new file mode 100644 index 0000000..7fc79a2 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M8.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M9-h.png b/ChaosDataPlayer/images/imgDatamodel/M9-h.png new file mode 100644 index 0000000..d882ee5 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M9-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M9-p.png b/ChaosDataPlayer/images/imgDatamodel/M9-p.png new file mode 100644 index 0000000..580c5f7 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M9-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/M9.png b/ChaosDataPlayer/images/imgDatamodel/M9.png new file mode 100644 index 0000000..d003fdf Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/M9.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/tabclose-h.png b/ChaosDataPlayer/images/imgDatamodel/tabclose-h.png new file mode 100644 index 0000000..79a6408 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/tabclose-h.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/tabclose-p.png b/ChaosDataPlayer/images/imgDatamodel/tabclose-p.png new file mode 100644 index 0000000..e218907 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/tabclose-p.png differ diff --git a/ChaosDataPlayer/images/imgDatamodel/tabclose.png b/ChaosDataPlayer/images/imgDatamodel/tabclose.png new file mode 100644 index 0000000..52640f3 Binary files /dev/null and b/ChaosDataPlayer/images/imgDatamodel/tabclose.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B1-h.png b/ChaosDataPlayer/images/imgMenuBar/B1-h.png new file mode 100644 index 0000000..4f323c2 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B1-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B1.png b/ChaosDataPlayer/images/imgMenuBar/B1.png new file mode 100644 index 0000000..293fb05 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B1.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B2-h.png b/ChaosDataPlayer/images/imgMenuBar/B2-h.png new file mode 100644 index 0000000..3110ecd Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B2-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B2.png b/ChaosDataPlayer/images/imgMenuBar/B2.png new file mode 100644 index 0000000..b2a027a Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B2.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B3-h.png b/ChaosDataPlayer/images/imgMenuBar/B3-h.png new file mode 100644 index 0000000..c826b8c Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B3-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B3.png b/ChaosDataPlayer/images/imgMenuBar/B3.png new file mode 100644 index 0000000..9ed69d0 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B3.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B4-h.png b/ChaosDataPlayer/images/imgMenuBar/B4-h.png new file mode 100644 index 0000000..38224b2 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B4-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B4.png b/ChaosDataPlayer/images/imgMenuBar/B4.png new file mode 100644 index 0000000..df74a59 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B4.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B5-h.png b/ChaosDataPlayer/images/imgMenuBar/B5-h.png new file mode 100644 index 0000000..f5aeda3 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B5-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B5.png b/ChaosDataPlayer/images/imgMenuBar/B5.png new file mode 100644 index 0000000..c0be3c9 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B5.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B6-h.png b/ChaosDataPlayer/images/imgMenuBar/B6-h.png new file mode 100644 index 0000000..7d2c711 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B6-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B6.png b/ChaosDataPlayer/images/imgMenuBar/B6.png new file mode 100644 index 0000000..acdab00 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B6.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B7-h.png b/ChaosDataPlayer/images/imgMenuBar/B7-h.png new file mode 100644 index 0000000..950623a Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B7-h.png differ diff --git a/ChaosDataPlayer/images/imgMenuBar/B7.png b/ChaosDataPlayer/images/imgMenuBar/B7.png new file mode 100644 index 0000000..2c50189 Binary files /dev/null and b/ChaosDataPlayer/images/imgMenuBar/B7.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/344.png b/ChaosDataPlayer/images/imgModelAction/344.png new file mode 100644 index 0000000..0e1454d Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/344.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/657.png b/ChaosDataPlayer/images/imgModelAction/657.png new file mode 100644 index 0000000..ce1fcfd Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/657.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/AC-h.png b/ChaosDataPlayer/images/imgModelAction/AC-h.png new file mode 100644 index 0000000..7c8e736 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/AC-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/AC-p.png b/ChaosDataPlayer/images/imgModelAction/AC-p.png new file mode 100644 index 0000000..a1ea486 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/AC-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/AC.png b/ChaosDataPlayer/images/imgModelAction/AC.png new file mode 100644 index 0000000..db48e2f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/AC.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Annotation-h.png b/ChaosDataPlayer/images/imgModelAction/Annotation-h.png new file mode 100644 index 0000000..611ed51 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Annotation-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Annotation-p.png b/ChaosDataPlayer/images/imgModelAction/Annotation-p.png new file mode 100644 index 0000000..939840a Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Annotation-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Annotation.png b/ChaosDataPlayer/images/imgModelAction/Annotation.png new file mode 100644 index 0000000..e0df71b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Annotation.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Annotation1.png b/ChaosDataPlayer/images/imgModelAction/Annotation1.png new file mode 100644 index 0000000..eb072a4 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Annotation1.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/AutoScaleXY.png b/ChaosDataPlayer/images/imgModelAction/AutoScaleXY.png new file mode 100644 index 0000000..f2dba62 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/AutoScaleXY.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Close.png b/ChaosDataPlayer/images/imgModelAction/Close.png new file mode 100644 index 0000000..9926c29 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Close.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Close_h.png b/ChaosDataPlayer/images/imgModelAction/Close_h.png new file mode 100644 index 0000000..aa4235f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Close_h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Close_p.png b/ChaosDataPlayer/images/imgModelAction/Close_p.png new file mode 100644 index 0000000..1c61ecb Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Close_p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Cursor.png b/ChaosDataPlayer/images/imgModelAction/Cursor.png new file mode 100644 index 0000000..abda6c6 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Cursor.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/DC.png b/ChaosDataPlayer/images/imgModelAction/DC.png new file mode 100644 index 0000000..d19f708 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/DC.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/HZ-h.png b/ChaosDataPlayer/images/imgModelAction/HZ-h.png new file mode 100644 index 0000000..6a29161 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/HZ-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/HZ.png b/ChaosDataPlayer/images/imgModelAction/HZ.png new file mode 100644 index 0000000..2f49403 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/HZ.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Integration.png b/ChaosDataPlayer/images/imgModelAction/Integration.png new file mode 100644 index 0000000..86e2e32 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Integration.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Open.png b/ChaosDataPlayer/images/imgModelAction/Open.png new file mode 100644 index 0000000..cb3ef1d Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Open.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Open_h.png b/ChaosDataPlayer/images/imgModelAction/Open_h.png new file mode 100644 index 0000000..7e076f3 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Open_h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Open_p.png b/ChaosDataPlayer/images/imgModelAction/Open_p.png new file mode 100644 index 0000000..0cb5282 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Open_p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Ord.png b/ChaosDataPlayer/images/imgModelAction/Ord.png new file mode 100644 index 0000000..2951591 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Ord.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Search-h.png b/ChaosDataPlayer/images/imgModelAction/Search-h.png new file mode 100644 index 0000000..cc03f9c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Search-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Search-p.png b/ChaosDataPlayer/images/imgModelAction/Search-p.png new file mode 100644 index 0000000..bfa911d Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Search-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Search.png b/ChaosDataPlayer/images/imgModelAction/Search.png new file mode 100644 index 0000000..b43a670 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Search.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Sound-d.png b/ChaosDataPlayer/images/imgModelAction/Sound-d.png new file mode 100644 index 0000000..b021842 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Sound-d.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Sound-h.png b/ChaosDataPlayer/images/imgModelAction/Sound-h.png new file mode 100644 index 0000000..efe0e2f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Sound-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Sound-p.png b/ChaosDataPlayer/images/imgModelAction/Sound-p.png new file mode 100644 index 0000000..bf6e474 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Sound-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Sound.png b/ChaosDataPlayer/images/imgModelAction/Sound.png new file mode 100644 index 0000000..8c8358f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Sound.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/TDBC-P.jpg b/ChaosDataPlayer/images/imgModelAction/TDBC-P.jpg new file mode 100644 index 0000000..13ae16f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/TDBC-P.jpg differ diff --git a/ChaosDataPlayer/images/imgModelAction/TDBC-h.png b/ChaosDataPlayer/images/imgModelAction/TDBC-h.png new file mode 100644 index 0000000..9024557 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/TDBC-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/TDBC-p.png b/ChaosDataPlayer/images/imgModelAction/TDBC-p.png new file mode 100644 index 0000000..d979acf Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/TDBC-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/TDBC.png b/ChaosDataPlayer/images/imgModelAction/TDBC.png new file mode 100644 index 0000000..cdb958b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/TDBC.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/Ord.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Ord.png new file mode 100644 index 0000000..55a4702 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Ord.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rad.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rad.png new file mode 100644 index 0000000..40acf6c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rad.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rpm.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rpm.png new file mode 100644 index 0000000..57e8bf1 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/Rpm.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 521.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 521.png new file mode 100644 index 0000000..6a29161 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 521.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 583.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 583.png new file mode 100644 index 0000000..2951591 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 583.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 584.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 584.png new file mode 100644 index 0000000..9fadd86 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 584.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 658.png b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 658.png new file mode 100644 index 0000000..2f49403 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/X坐标变化/组 658.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom-XY.png b/ChaosDataPlayer/images/imgModelAction/Zoom-XY.png new file mode 100644 index 0000000..e52083a Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom-XY.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom-h.png b/ChaosDataPlayer/images/imgModelAction/Zoom-h.png new file mode 100644 index 0000000..dcd5ac3 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom-p.png b/ChaosDataPlayer/images/imgModelAction/Zoom-p.png new file mode 100644 index 0000000..bc64fd2 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom-xy-h.png b/ChaosDataPlayer/images/imgModelAction/Zoom-xy-h.png new file mode 100644 index 0000000..8170845 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom-xy-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom-xy-p.png b/ChaosDataPlayer/images/imgModelAction/Zoom-xy-p.png new file mode 100644 index 0000000..885c3ce Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom-xy-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom.png b/ChaosDataPlayer/images/imgModelAction/Zoom.png new file mode 100644 index 0000000..d7d43d3 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom11.png b/ChaosDataPlayer/images/imgModelAction/Zoom11.png new file mode 100644 index 0000000..b3f307e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom11.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom_Box.png b/ChaosDataPlayer/images/imgModelAction/Zoom_Box.png new file mode 100644 index 0000000..d5bccbf Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom_Box.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom_X.png b/ChaosDataPlayer/images/imgModelAction/Zoom_X.png new file mode 100644 index 0000000..d10e424 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom_X.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom_Y.png b/ChaosDataPlayer/images/imgModelAction/Zoom_Y.png new file mode 100644 index 0000000..0e5a1ab Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom_Y.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/Zoom_xy.png b/ChaosDataPlayer/images/imgModelAction/Zoom_xy.png new file mode 100644 index 0000000..ce1fcfd Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/Zoom_xy.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/ac-2.png b/ChaosDataPlayer/images/imgModelAction/ac-2.png new file mode 100644 index 0000000..a1ea486 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/ac-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/acdc/组 629.png b/ChaosDataPlayer/images/imgModelAction/acdc/组 629.png new file mode 100644 index 0000000..7c8e736 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/acdc/组 629.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/acdc/组 683.png b/ChaosDataPlayer/images/imgModelAction/acdc/组 683.png new file mode 100644 index 0000000..db48e2f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/acdc/组 683.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/acdc/组 684.png b/ChaosDataPlayer/images/imgModelAction/acdc/组 684.png new file mode 100644 index 0000000..d19f708 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/acdc/组 684.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/arf-h.png b/ChaosDataPlayer/images/imgModelAction/arf-h.png new file mode 100644 index 0000000..3e1d03f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/arf-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/arf-p.png b/ChaosDataPlayer/images/imgModelAction/arf-p.png new file mode 100644 index 0000000..fa99016 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/arf-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/arf.png b/ChaosDataPlayer/images/imgModelAction/arf.png new file mode 100644 index 0000000..549b65f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/arf.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisX-h.png b/ChaosDataPlayer/images/imgModelAction/axisX-h.png new file mode 100644 index 0000000..285547b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisX-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisX-p.png b/ChaosDataPlayer/images/imgModelAction/axisX-p.png new file mode 100644 index 0000000..9c6e698 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisX-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisX.png b/ChaosDataPlayer/images/imgModelAction/axisX.png new file mode 100644 index 0000000..2e780dc Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisX.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisY-h.png b/ChaosDataPlayer/images/imgModelAction/axisY-h.png new file mode 100644 index 0000000..cf318e5 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisY-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisY-p.png b/ChaosDataPlayer/images/imgModelAction/axisY-p.png new file mode 100644 index 0000000..c949eaf Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisY-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/axisY.png b/ChaosDataPlayer/images/imgModelAction/axisY.png new file mode 100644 index 0000000..f1df36c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/axisY.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/biandai.png b/ChaosDataPlayer/images/imgModelAction/biandai.png new file mode 100644 index 0000000..42ca6ce Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/biandai.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/doubleIntegration.png b/ChaosDataPlayer/images/imgModelAction/doubleIntegration.png new file mode 100644 index 0000000..58fcdf9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/doubleIntegration.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/doublearf.png b/ChaosDataPlayer/images/imgModelAction/doublearf.png new file mode 100644 index 0000000..48a4b82 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/doublearf.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/fengzhi.png b/ChaosDataPlayer/images/imgModelAction/fengzhi.png new file mode 100644 index 0000000..897b7ce Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/fengzhi.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/gb-h.png b/ChaosDataPlayer/images/imgModelAction/gb-h.png new file mode 100644 index 0000000..bcc8dc8 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/gb-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/gb-p.png b/ChaosDataPlayer/images/imgModelAction/gb-p.png new file mode 100644 index 0000000..d6b519c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/gb-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/gb1.png b/ChaosDataPlayer/images/imgModelAction/gb1.png new file mode 100644 index 0000000..55cec3a Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/gb1.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/hand-h.png b/ChaosDataPlayer/images/imgModelAction/hand-h.png new file mode 100644 index 0000000..d60e0a7 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/hand-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/hand-p.png b/ChaosDataPlayer/images/imgModelAction/hand-p.png new file mode 100644 index 0000000..b25eb54 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/hand-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/hand.png b/ChaosDataPlayer/images/imgModelAction/hand.png new file mode 100644 index 0000000..bc3e737 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/hand.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/hand1.png b/ChaosDataPlayer/images/imgModelAction/hand1.png new file mode 100644 index 0000000..3f827bc Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/hand1.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/hz-2.png b/ChaosDataPlayer/images/imgModelAction/hz-2.png new file mode 100644 index 0000000..11ac680 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/hz-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/lvbo-h.png b/ChaosDataPlayer/images/imgModelAction/lvbo-h.png new file mode 100644 index 0000000..e9a2cbb Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/lvbo-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/lvbo-p.jpg b/ChaosDataPlayer/images/imgModelAction/lvbo-p.jpg new file mode 100644 index 0000000..9626ea9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/lvbo-p.jpg differ diff --git a/ChaosDataPlayer/images/imgModelAction/lvbo-p.png b/ChaosDataPlayer/images/imgModelAction/lvbo-p.png new file mode 100644 index 0000000..8e7a970 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/lvbo-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/lvbo.png b/ChaosDataPlayer/images/imgModelAction/lvbo.png new file mode 100644 index 0000000..59ff2c5 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/lvbo.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/measure-d.png b/ChaosDataPlayer/images/imgModelAction/measure-d.png new file mode 100644 index 0000000..6879b6e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/measure-d.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/measure-h.png b/ChaosDataPlayer/images/imgModelAction/measure-h.png new file mode 100644 index 0000000..218a8d9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/measure-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/measure-p.png b/ChaosDataPlayer/images/imgModelAction/measure-p.png new file mode 100644 index 0000000..53cb8de Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/measure-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/measure.png b/ChaosDataPlayer/images/imgModelAction/measure.png new file mode 100644 index 0000000..f864558 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/measure.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/pv-2.png b/ChaosDataPlayer/images/imgModelAction/pv-2.png new file mode 100644 index 0000000..4cc712d Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/pv-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/realTime-d.png b/ChaosDataPlayer/images/imgModelAction/realTime-d.png new file mode 100644 index 0000000..43cf7f8 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/realTime-d.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/realTime-h.png b/ChaosDataPlayer/images/imgModelAction/realTime-h.png new file mode 100644 index 0000000..7308bd6 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/realTime-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/realTime-p.png b/ChaosDataPlayer/images/imgModelAction/realTime-p.png new file mode 100644 index 0000000..640cd4b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/realTime-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/realTime.png b/ChaosDataPlayer/images/imgModelAction/realTime.png new file mode 100644 index 0000000..3fe894e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/realTime.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/rpm.png b/ChaosDataPlayer/images/imgModelAction/rpm.png new file mode 100644 index 0000000..9fadd86 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/rpm.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/setScales-d.png b/ChaosDataPlayer/images/imgModelAction/setScales-d.png new file mode 100644 index 0000000..ee5cf93 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/setScales-d.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/setScales-h.png b/ChaosDataPlayer/images/imgModelAction/setScales-h.png new file mode 100644 index 0000000..b179779 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/setScales-h.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/setScales-p.png b/ChaosDataPlayer/images/imgModelAction/setScales-p.png new file mode 100644 index 0000000..87aed59 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/setScales-p.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/setScales.png b/ChaosDataPlayer/images/imgModelAction/setScales.png new file mode 100644 index 0000000..290e338 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/setScales.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/xiebo.png b/ChaosDataPlayer/images/imgModelAction/xiebo.png new file mode 100644 index 0000000..4e09aef Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/xiebo.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/θ-3.png b/ChaosDataPlayer/images/imgModelAction/θ-3.png new file mode 100644 index 0000000..7b95672 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/θ-3.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/∂-2.png b/ChaosDataPlayer/images/imgModelAction/∂-2.png new file mode 100644 index 0000000..fa99016 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/∂-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/两个--2.png b/ChaosDataPlayer/images/imgModelAction/两个--2.png new file mode 100644 index 0000000..8cd6729 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/两个--2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/伯德图-2.png b/ChaosDataPlayer/images/imgModelAction/伯德图-2.png new file mode 100644 index 0000000..05d394b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/伯德图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标-2.png b/ChaosDataPlayer/images/imgModelAction/光标-2.png new file mode 100644 index 0000000..7529f4c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标/组 659.png b/ChaosDataPlayer/images/imgModelAction/光标/组 659.png new file mode 100644 index 0000000..55cec3a Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标/组 659.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标/组 700.png b/ChaosDataPlayer/images/imgModelAction/光标/组 700.png new file mode 100644 index 0000000..77e9d4e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标/组 700.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标/组 701.png b/ChaosDataPlayer/images/imgModelAction/光标/组 701.png new file mode 100644 index 0000000..e2d84b9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标/组 701.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标/组 702.png b/ChaosDataPlayer/images/imgModelAction/光标/组 702.png new file mode 100644 index 0000000..4204b76 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标/组 702.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/光标/组 703.png b/ChaosDataPlayer/images/imgModelAction/光标/组 703.png new file mode 100644 index 0000000..26e0610 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/光标/组 703.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/喇叭.png b/ChaosDataPlayer/images/imgModelAction/喇叭.png new file mode 100644 index 0000000..469d41a Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/喇叭.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/展开-框.png b/ChaosDataPlayer/images/imgModelAction/展开-框.png new file mode 100644 index 0000000..f5ba817 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/展开-框.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/峰值光标-2.png b/ChaosDataPlayer/images/imgModelAction/峰值光标-2.png new file mode 100644 index 0000000..88c2db2 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/峰值光标-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/度量-2.png b/ChaosDataPlayer/images/imgModelAction/度量-2.png new file mode 100644 index 0000000..53cb8de Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/度量-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/手-3.png b/ChaosDataPlayer/images/imgModelAction/手-3.png new file mode 100644 index 0000000..0f6b7c7 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/手-3.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/折现图-2.png b/ChaosDataPlayer/images/imgModelAction/折现图-2.png new file mode 100644 index 0000000..9e92183 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/折现图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/时域图-2.png b/ChaosDataPlayer/images/imgModelAction/时域图-2.png new file mode 100644 index 0000000..6408a09 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/时域图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/极坐标图-2.png b/ChaosDataPlayer/images/imgModelAction/极坐标图-2.png new file mode 100644 index 0000000..1045b33 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/极坐标图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/柱状图-2.png b/ChaosDataPlayer/images/imgModelAction/柱状图-2.png new file mode 100644 index 0000000..2cf61b9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/柱状图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/瀑布图-2.png b/ChaosDataPlayer/images/imgModelAction/瀑布图-2.png new file mode 100644 index 0000000..a6ce435 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/瀑布图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/直播-0.png b/ChaosDataPlayer/images/imgModelAction/直播-0.png new file mode 100644 index 0000000..43cf7f8 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/直播-0.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/直播-2.png b/ChaosDataPlayer/images/imgModelAction/直播-2.png new file mode 100644 index 0000000..28afcea Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/直播-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/∫.png b/ChaosDataPlayer/images/imgModelAction/积分微分/∫.png new file mode 100644 index 0000000..ac96333 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/∫.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/∫∫.png b/ChaosDataPlayer/images/imgModelAction/积分微分/∫∫.png new file mode 100644 index 0000000..4155432 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/∫∫.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 507.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 507.png new file mode 100644 index 0000000..549b65f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 507.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 508.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 508.png new file mode 100644 index 0000000..86e2e32 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 508.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 538.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 538.png new file mode 100644 index 0000000..3e1d03f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 538.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 686.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 686.png new file mode 100644 index 0000000..48a4b82 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 686.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 688.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 688.png new file mode 100644 index 0000000..58fcdf9 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 688.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 696.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 696.png new file mode 100644 index 0000000..73737c7 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 696.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/积分微分/组 697.png b/ChaosDataPlayer/images/imgModelAction/积分微分/组 697.png new file mode 100644 index 0000000..74957a7 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/积分微分/组 697.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 508.png b/ChaosDataPlayer/images/imgModelAction/组 508.png new file mode 100644 index 0000000..86e2e32 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 508.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 510.png b/ChaosDataPlayer/images/imgModelAction/组 510.png new file mode 100644 index 0000000..529396b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 510.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 548.png b/ChaosDataPlayer/images/imgModelAction/组 548.png new file mode 100644 index 0000000..8fa9003 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 548.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 581.png b/ChaosDataPlayer/images/imgModelAction/组 581.png new file mode 100644 index 0000000..3f827bc Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 581.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 624.png b/ChaosDataPlayer/images/imgModelAction/组 624.png new file mode 100644 index 0000000..1143212 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 624.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 656.png b/ChaosDataPlayer/images/imgModelAction/组 656.png new file mode 100644 index 0000000..b3f307e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 656.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/组 663.png b/ChaosDataPlayer/images/imgModelAction/组 663.png new file mode 100644 index 0000000..8c8358f Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/组 663.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/缩小-2.png b/ChaosDataPlayer/images/imgModelAction/缩小-2.png new file mode 100644 index 0000000..0424591 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/缩小-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/虚线-2.png b/ChaosDataPlayer/images/imgModelAction/虚线-2.png new file mode 100644 index 0000000..33e529b Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/虚线-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/谐波光标-2.png b/ChaosDataPlayer/images/imgModelAction/谐波光标-2.png new file mode 100644 index 0000000..b257c0c Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/谐波光标-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/趋势图-2.png b/ChaosDataPlayer/images/imgModelAction/趋势图-2.png new file mode 100644 index 0000000..bcf8e36 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/趋势图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/趋势图-按钮.png b/ChaosDataPlayer/images/imgModelAction/趋势图-按钮.png new file mode 100644 index 0000000..f34c02e Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/趋势图-按钮.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/轴心位置图-2.png b/ChaosDataPlayer/images/imgModelAction/轴心位置图-2.png new file mode 100644 index 0000000..c57f569 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/轴心位置图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/轴心轨迹图-2.png b/ChaosDataPlayer/images/imgModelAction/轴心轨迹图-2.png new file mode 100644 index 0000000..5ce4eee Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/轴心轨迹图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/边带光标-2.png b/ChaosDataPlayer/images/imgModelAction/边带光标-2.png new file mode 100644 index 0000000..edc7237 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/边带光标-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/频域图-2.png b/ChaosDataPlayer/images/imgModelAction/频域图-2.png new file mode 100644 index 0000000..3aa8450 Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/频域图-2.png differ diff --git a/ChaosDataPlayer/images/imgModelAction/鼠标1-2.png b/ChaosDataPlayer/images/imgModelAction/鼠标1-2.png new file mode 100644 index 0000000..da70bac Binary files /dev/null and b/ChaosDataPlayer/images/imgModelAction/鼠标1-2.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B10-h.png b/ChaosDataPlayer/images/imgPlay/B10-h.png new file mode 100644 index 0000000..b346d63 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B10-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B10.png b/ChaosDataPlayer/images/imgPlay/B10.png new file mode 100644 index 0000000..ad90c36 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B10.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B11-h.png b/ChaosDataPlayer/images/imgPlay/B11-h.png new file mode 100644 index 0000000..dc82c2d Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B11-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B11.png b/ChaosDataPlayer/images/imgPlay/B11.png new file mode 100644 index 0000000..91c5047 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B11.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B12-h.png b/ChaosDataPlayer/images/imgPlay/B12-h.png new file mode 100644 index 0000000..9ff21da Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B12-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B12.png b/ChaosDataPlayer/images/imgPlay/B12.png new file mode 100644 index 0000000..7aa552c Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B12.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B13-h.png b/ChaosDataPlayer/images/imgPlay/B13-h.png new file mode 100644 index 0000000..8341e1f Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B13-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B13.png b/ChaosDataPlayer/images/imgPlay/B13.png new file mode 100644 index 0000000..baa34ef Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B13.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B14-h.png b/ChaosDataPlayer/images/imgPlay/B14-h.png new file mode 100644 index 0000000..7393161 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B14-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B14.png b/ChaosDataPlayer/images/imgPlay/B14.png new file mode 100644 index 0000000..9fc58c3 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B14.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B15.png b/ChaosDataPlayer/images/imgPlay/B15.png new file mode 100644 index 0000000..12cca19 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B15.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B16.png b/ChaosDataPlayer/images/imgPlay/B16.png new file mode 100644 index 0000000..6981d7a Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B16.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B8-h.png b/ChaosDataPlayer/images/imgPlay/B8-h.png new file mode 100644 index 0000000..d41ebbb Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B8-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B8.png b/ChaosDataPlayer/images/imgPlay/B8.png new file mode 100644 index 0000000..a82a2d2 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B8.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B9-h.png b/ChaosDataPlayer/images/imgPlay/B9-h.png new file mode 100644 index 0000000..456cabf Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B9-h.png differ diff --git a/ChaosDataPlayer/images/imgPlay/B9.png b/ChaosDataPlayer/images/imgPlay/B9.png new file mode 100644 index 0000000..bc32556 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/B9.png differ diff --git a/ChaosDataPlayer/images/imgPlay/停止-1.png b/ChaosDataPlayer/images/imgPlay/停止-1.png new file mode 100644 index 0000000..bff589e Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/停止-1.png differ diff --git a/ChaosDataPlayer/images/imgPlay/回到开始-1.png b/ChaosDataPlayer/images/imgPlay/回到开始-1.png new file mode 100644 index 0000000..c7f2d25 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/回到开始-1.png differ diff --git a/ChaosDataPlayer/images/imgPlay/回到结尾-1.png b/ChaosDataPlayer/images/imgPlay/回到结尾-1.png new file mode 100644 index 0000000..86ebb0f Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/回到结尾-1.png differ diff --git a/ChaosDataPlayer/images/imgPlay/快进-1.png b/ChaosDataPlayer/images/imgPlay/快进-1.png new file mode 100644 index 0000000..e816e44 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/快进-1.png differ diff --git a/ChaosDataPlayer/images/imgPlay/快进1秒-1.png b/ChaosDataPlayer/images/imgPlay/快进1秒-1.png new file mode 100644 index 0000000..458b1a8 Binary files /dev/null and b/ChaosDataPlayer/images/imgPlay/快进1秒-1.png differ diff --git a/ChaosDataPlayer/images/imgSystem/ICON.ico b/ChaosDataPlayer/images/imgSystem/ICON.ico new file mode 100644 index 0000000..c37c58e Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/ICON.ico differ diff --git a/ChaosDataPlayer/images/imgSystem/systemIcon.png b/ChaosDataPlayer/images/imgSystem/systemIcon.png new file mode 100644 index 0000000..dbf7097 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/systemIcon.png differ diff --git a/ChaosDataPlayer/images/imgSystem/关闭.png b/ChaosDataPlayer/images/imgSystem/关闭.png new file mode 100644 index 0000000..dfab52b Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/关闭.png differ diff --git a/ChaosDataPlayer/images/imgSystem/最大化.png b/ChaosDataPlayer/images/imgSystem/最大化.png new file mode 100644 index 0000000..18d4071 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/最大化.png differ diff --git a/ChaosDataPlayer/images/imgSystem/最小化.png b/ChaosDataPlayer/images/imgSystem/最小化.png new file mode 100644 index 0000000..66d4d97 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/最小化.png differ diff --git a/ChaosDataPlayer/images/imgSystem/组 717.jpg b/ChaosDataPlayer/images/imgSystem/组 717.jpg new file mode 100644 index 0000000..7bf6aa5 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/组 717.jpg differ diff --git a/ChaosDataPlayer/images/imgSystem/组 718.jpg b/ChaosDataPlayer/images/imgSystem/组 718.jpg new file mode 100644 index 0000000..9fd68af Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/组 718.jpg differ diff --git a/ChaosDataPlayer/images/imgSystem/组 719.jpg b/ChaosDataPlayer/images/imgSystem/组 719.jpg new file mode 100644 index 0000000..0410121 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/组 719.jpg differ diff --git a/ChaosDataPlayer/images/imgSystem/设 置.png b/ChaosDataPlayer/images/imgSystem/设 置.png new file mode 100644 index 0000000..f9d9a0a Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/设 置.png differ diff --git a/ChaosDataPlayer/images/imgSystem/问好 (1).png b/ChaosDataPlayer/images/imgSystem/问好 (1).png new file mode 100644 index 0000000..488a8b5 Binary files /dev/null and b/ChaosDataPlayer/images/imgSystem/问好 (1).png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/artic66.png b/ChaosDataPlayer/images/imgTreeIcon/artic66.png new file mode 100644 index 0000000..88a19ec Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/artic66.png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/channel.png b/ChaosDataPlayer/images/imgTreeIcon/channel.png new file mode 100644 index 0000000..3c49796 Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/channel.png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/config.png b/ChaosDataPlayer/images/imgTreeIcon/config.png new file mode 100644 index 0000000..256ca24 Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/config.png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/data.png b/ChaosDataPlayer/images/imgTreeIcon/data.png new file mode 100644 index 0000000..520051f Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/data.png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/remove2.png b/ChaosDataPlayer/images/imgTreeIcon/remove2.png new file mode 100644 index 0000000..e1bf818 Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/remove2.png differ diff --git a/ChaosDataPlayer/images/imgTreeIcon/remove6.png b/ChaosDataPlayer/images/imgTreeIcon/remove6.png new file mode 100644 index 0000000..3b53dfd Binary files /dev/null and b/ChaosDataPlayer/images/imgTreeIcon/remove6.png differ diff --git a/ChaosDataPlayer/images/line.png b/ChaosDataPlayer/images/line.png new file mode 100644 index 0000000..4efbd7e Binary files /dev/null and b/ChaosDataPlayer/images/line.png differ diff --git a/ChaosDataPlayer/images/loading.gif b/ChaosDataPlayer/images/loading.gif new file mode 100644 index 0000000..4117934 Binary files /dev/null and b/ChaosDataPlayer/images/loading.gif differ diff --git a/ChaosDataPlayer/images/logo.png b/ChaosDataPlayer/images/logo.png new file mode 100644 index 0000000..729a28b Binary files /dev/null and b/ChaosDataPlayer/images/logo.png differ diff --git a/ChaosDataPlayer/images/logo1.png b/ChaosDataPlayer/images/logo1.png new file mode 100644 index 0000000..36c7618 Binary files /dev/null and b/ChaosDataPlayer/images/logo1.png differ diff --git a/ChaosDataPlayer/images/max_h.png b/ChaosDataPlayer/images/max_h.png new file mode 100644 index 0000000..fe3690d Binary files /dev/null and b/ChaosDataPlayer/images/max_h.png differ diff --git a/ChaosDataPlayer/images/max_n.png b/ChaosDataPlayer/images/max_n.png new file mode 100644 index 0000000..0b84eaa Binary files /dev/null and b/ChaosDataPlayer/images/max_n.png differ diff --git a/ChaosDataPlayer/images/max_s.png b/ChaosDataPlayer/images/max_s.png new file mode 100644 index 0000000..ed51dc1 Binary files /dev/null and b/ChaosDataPlayer/images/max_s.png differ diff --git a/ChaosDataPlayer/images/menu/_desktop.ini b/ChaosDataPlayer/images/menu/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/menu/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/menu/bottom_line.png b/ChaosDataPlayer/images/menu/bottom_line.png new file mode 100644 index 0000000..b2fbcb9 Binary files /dev/null and b/ChaosDataPlayer/images/menu/bottom_line.png differ diff --git a/ChaosDataPlayer/images/menu/cur_select.png b/ChaosDataPlayer/images/menu/cur_select.png new file mode 100644 index 0000000..c0934ae Binary files /dev/null and b/ChaosDataPlayer/images/menu/cur_select.png differ diff --git a/ChaosDataPlayer/images/menu/has-sub-b.png b/ChaosDataPlayer/images/menu/has-sub-b.png new file mode 100644 index 0000000..18637c0 Binary files /dev/null and b/ChaosDataPlayer/images/menu/has-sub-b.png differ diff --git a/ChaosDataPlayer/images/menu/item_bg.png b/ChaosDataPlayer/images/menu/item_bg.png new file mode 100644 index 0000000..41ea726 Binary files /dev/null and b/ChaosDataPlayer/images/menu/item_bg.png differ diff --git a/ChaosDataPlayer/images/menu/item_enabled.png b/ChaosDataPlayer/images/menu/item_enabled.png new file mode 100644 index 0000000..db3f501 Binary files /dev/null and b/ChaosDataPlayer/images/menu/item_enabled.png differ diff --git a/ChaosDataPlayer/images/menu/menu_bg.png b/ChaosDataPlayer/images/menu/menu_bg.png new file mode 100644 index 0000000..f3efe05 Binary files /dev/null and b/ChaosDataPlayer/images/menu/menu_bg.png differ diff --git a/ChaosDataPlayer/images/min_h.png b/ChaosDataPlayer/images/min_h.png new file mode 100644 index 0000000..3da5f27 Binary files /dev/null and b/ChaosDataPlayer/images/min_h.png differ diff --git a/ChaosDataPlayer/images/min_n.png b/ChaosDataPlayer/images/min_n.png new file mode 100644 index 0000000..538a435 Binary files /dev/null and b/ChaosDataPlayer/images/min_n.png differ diff --git a/ChaosDataPlayer/images/min_s.png b/ChaosDataPlayer/images/min_s.png new file mode 100644 index 0000000..1bc543b Binary files /dev/null and b/ChaosDataPlayer/images/min_s.png differ diff --git a/ChaosDataPlayer/images/notice/_desktop.ini b/ChaosDataPlayer/images/notice/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/notice/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/notice/error.png b/ChaosDataPlayer/images/notice/error.png new file mode 100644 index 0000000..3482c50 Binary files /dev/null and b/ChaosDataPlayer/images/notice/error.png differ diff --git a/ChaosDataPlayer/images/notice/success - 副本.png b/ChaosDataPlayer/images/notice/success - 副本.png new file mode 100644 index 0000000..e9b3e45 Binary files /dev/null and b/ChaosDataPlayer/images/notice/success - 副本.png differ diff --git a/ChaosDataPlayer/images/notice/success.png b/ChaosDataPlayer/images/notice/success.png new file mode 100644 index 0000000..3ab9160 Binary files /dev/null and b/ChaosDataPlayer/images/notice/success.png differ diff --git a/ChaosDataPlayer/images/notice/warning.png b/ChaosDataPlayer/images/notice/warning.png new file mode 100644 index 0000000..b9500be Binary files /dev/null and b/ChaosDataPlayer/images/notice/warning.png differ diff --git a/ChaosDataPlayer/images/operate/_desktop.ini b/ChaosDataPlayer/images/operate/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/operate/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/operate/del.png b/ChaosDataPlayer/images/operate/del.png new file mode 100644 index 0000000..218829d Binary files /dev/null and b/ChaosDataPlayer/images/operate/del.png differ diff --git a/ChaosDataPlayer/images/operate/del_h.png b/ChaosDataPlayer/images/operate/del_h.png new file mode 100644 index 0000000..da97af1 Binary files /dev/null and b/ChaosDataPlayer/images/operate/del_h.png differ diff --git a/ChaosDataPlayer/images/operate/del_s.png b/ChaosDataPlayer/images/operate/del_s.png new file mode 100644 index 0000000..22bec25 Binary files /dev/null and b/ChaosDataPlayer/images/operate/del_s.png differ diff --git a/ChaosDataPlayer/images/operate/edit.png b/ChaosDataPlayer/images/operate/edit.png new file mode 100644 index 0000000..2e59927 Binary files /dev/null and b/ChaosDataPlayer/images/operate/edit.png differ diff --git a/ChaosDataPlayer/images/operate/edit_h.png b/ChaosDataPlayer/images/operate/edit_h.png new file mode 100644 index 0000000..df703be Binary files /dev/null and b/ChaosDataPlayer/images/operate/edit_h.png differ diff --git a/ChaosDataPlayer/images/operate/edit_s.png b/ChaosDataPlayer/images/operate/edit_s.png new file mode 100644 index 0000000..9a54711 Binary files /dev/null and b/ChaosDataPlayer/images/operate/edit_s.png differ diff --git a/ChaosDataPlayer/images/qslider/_desktop.ini b/ChaosDataPlayer/images/qslider/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/qslider/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/qslider/flag.png b/ChaosDataPlayer/images/qslider/flag.png new file mode 100644 index 0000000..2f073c5 Binary files /dev/null and b/ChaosDataPlayer/images/qslider/flag.png differ diff --git a/ChaosDataPlayer/images/qslider/pg.png b/ChaosDataPlayer/images/qslider/pg.png new file mode 100644 index 0000000..aba9b0e Binary files /dev/null and b/ChaosDataPlayer/images/qslider/pg.png differ diff --git a/ChaosDataPlayer/images/qslider/pg_bg.png b/ChaosDataPlayer/images/qslider/pg_bg.png new file mode 100644 index 0000000..b01c1bb Binary files /dev/null and b/ChaosDataPlayer/images/qslider/pg_bg.png differ diff --git a/ChaosDataPlayer/images/restore_h.png b/ChaosDataPlayer/images/restore_h.png new file mode 100644 index 0000000..9b7e460 Binary files /dev/null and b/ChaosDataPlayer/images/restore_h.png differ diff --git a/ChaosDataPlayer/images/restore_n.png b/ChaosDataPlayer/images/restore_n.png new file mode 100644 index 0000000..88faa6b Binary files /dev/null and b/ChaosDataPlayer/images/restore_n.png differ diff --git a/ChaosDataPlayer/images/restore_s.png b/ChaosDataPlayer/images/restore_s.png new file mode 100644 index 0000000..8018a3d Binary files /dev/null and b/ChaosDataPlayer/images/restore_s.png differ diff --git a/ChaosDataPlayer/images/showChannel.png b/ChaosDataPlayer/images/showChannel.png new file mode 100644 index 0000000..f5ba817 Binary files /dev/null and b/ChaosDataPlayer/images/showChannel.png differ diff --git a/ChaosDataPlayer/images/showChannel_.png b/ChaosDataPlayer/images/showChannel_.png new file mode 100644 index 0000000..04a6f40 Binary files /dev/null and b/ChaosDataPlayer/images/showChannel_.png differ diff --git a/ChaosDataPlayer/images/spinbox/_desktop.ini b/ChaosDataPlayer/images/spinbox/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/spinbox/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/spinbox/down_normal.png b/ChaosDataPlayer/images/spinbox/down_normal.png new file mode 100644 index 0000000..1bfcb1a Binary files /dev/null and b/ChaosDataPlayer/images/spinbox/down_normal.png differ diff --git a/ChaosDataPlayer/images/spinbox/down_select.png b/ChaosDataPlayer/images/spinbox/down_select.png new file mode 100644 index 0000000..afc5bcc Binary files /dev/null and b/ChaosDataPlayer/images/spinbox/down_select.png differ diff --git a/ChaosDataPlayer/images/spinbox/up_normal.png b/ChaosDataPlayer/images/spinbox/up_normal.png new file mode 100644 index 0000000..0073139 Binary files /dev/null and b/ChaosDataPlayer/images/spinbox/up_normal.png differ diff --git a/ChaosDataPlayer/images/spinbox/up_select.png b/ChaosDataPlayer/images/spinbox/up_select.png new file mode 100644 index 0000000..7659b34 Binary files /dev/null and b/ChaosDataPlayer/images/spinbox/up_select.png differ diff --git a/ChaosDataPlayer/images/table/_desktop.ini b/ChaosDataPlayer/images/table/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/table/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/table/arrow_down.png b/ChaosDataPlayer/images/table/arrow_down.png new file mode 100644 index 0000000..0eb0c9c Binary files /dev/null and b/ChaosDataPlayer/images/table/arrow_down.png differ diff --git a/ChaosDataPlayer/images/table/arrow_up.png b/ChaosDataPlayer/images/table/arrow_up.png new file mode 100644 index 0000000..c9c260f Binary files /dev/null and b/ChaosDataPlayer/images/table/arrow_up.png differ diff --git a/ChaosDataPlayer/images/table/divLine.png b/ChaosDataPlayer/images/table/divLine.png new file mode 100644 index 0000000..14cb97a Binary files /dev/null and b/ChaosDataPlayer/images/table/divLine.png differ diff --git a/ChaosDataPlayer/images/table/head.png b/ChaosDataPlayer/images/table/head.png new file mode 100644 index 0000000..ebbe6a3 Binary files /dev/null and b/ChaosDataPlayer/images/table/head.png differ diff --git a/ChaosDataPlayer/images/table/head_bg.png b/ChaosDataPlayer/images/table/head_bg.png new file mode 100644 index 0000000..ebbe6a3 Binary files /dev/null and b/ChaosDataPlayer/images/table/head_bg.png differ diff --git a/ChaosDataPlayer/images/table/head_split.png b/ChaosDataPlayer/images/table/head_split.png new file mode 100644 index 0000000..14cb97a Binary files /dev/null and b/ChaosDataPlayer/images/table/head_split.png differ diff --git a/ChaosDataPlayer/images/tabwidget/Thumbs.db b/ChaosDataPlayer/images/tabwidget/Thumbs.db new file mode 100644 index 0000000..b4b4ffa Binary files /dev/null and b/ChaosDataPlayer/images/tabwidget/Thumbs.db differ diff --git a/ChaosDataPlayer/images/tabwidget/_desktop.ini b/ChaosDataPlayer/images/tabwidget/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/tabwidget/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/tabwidget/tab1_normal.png b/ChaosDataPlayer/images/tabwidget/tab1_normal.png new file mode 100644 index 0000000..cc2a9d8 Binary files /dev/null and b/ChaosDataPlayer/images/tabwidget/tab1_normal.png differ diff --git a/ChaosDataPlayer/images/tabwidget/tab1_select.png b/ChaosDataPlayer/images/tabwidget/tab1_select.png new file mode 100644 index 0000000..e5cf9e5 Binary files /dev/null and b/ChaosDataPlayer/images/tabwidget/tab1_select.png differ diff --git a/ChaosDataPlayer/images/tabwidget/tab2_normal.png b/ChaosDataPlayer/images/tabwidget/tab2_normal.png new file mode 100644 index 0000000..c364739 Binary files /dev/null and b/ChaosDataPlayer/images/tabwidget/tab2_normal.png differ diff --git a/ChaosDataPlayer/images/tabwidget/tab2_select.png b/ChaosDataPlayer/images/tabwidget/tab2_select.png new file mode 100644 index 0000000..bcd08f9 Binary files /dev/null and b/ChaosDataPlayer/images/tabwidget/tab2_select.png differ diff --git a/ChaosDataPlayer/images/tree/_desktop.ini b/ChaosDataPlayer/images/tree/_desktop.ini new file mode 100644 index 0000000..bf2d8c1 --- /dev/null +++ b/ChaosDataPlayer/images/tree/_desktop.ini @@ -0,0 +1 @@ +2017/5/2 \ No newline at end of file diff --git a/ChaosDataPlayer/images/tree/branch-end.png b/ChaosDataPlayer/images/tree/branch-end.png new file mode 100644 index 0000000..9a063c1 Binary files /dev/null and b/ChaosDataPlayer/images/tree/branch-end.png differ diff --git a/ChaosDataPlayer/images/tree/branch-more.png b/ChaosDataPlayer/images/tree/branch-more.png new file mode 100644 index 0000000..48bc573 Binary files /dev/null and b/ChaosDataPlayer/images/tree/branch-more.png differ diff --git a/ChaosDataPlayer/images/tree/expand.png b/ChaosDataPlayer/images/tree/expand.png new file mode 100644 index 0000000..2864ccb Binary files /dev/null and b/ChaosDataPlayer/images/tree/expand.png differ diff --git a/ChaosDataPlayer/images/tree/shrink.png b/ChaosDataPlayer/images/tree/shrink.png new file mode 100644 index 0000000..c816b1e Binary files /dev/null and b/ChaosDataPlayer/images/tree/shrink.png differ diff --git a/ChaosDataPlayer/images/tree/vline.png b/ChaosDataPlayer/images/tree/vline.png new file mode 100644 index 0000000..62f3d0c Binary files /dev/null and b/ChaosDataPlayer/images/tree/vline.png differ diff --git a/ChaosDataPlayer/images/加载条.gif.zip b/ChaosDataPlayer/images/加载条.gif.zip new file mode 100644 index 0000000..7e415be Binary files /dev/null and b/ChaosDataPlayer/images/加载条.gif.zip differ diff --git a/ChaosDataPlayer/images/加载条.gif/__MACOSX/._加载条.gif b/ChaosDataPlayer/images/加载条.gif/__MACOSX/._加载条.gif new file mode 100644 index 0000000..2e91f3e Binary files /dev/null and b/ChaosDataPlayer/images/加载条.gif/__MACOSX/._加载条.gif differ diff --git a/ChaosDataPlayer/images/加载条.gif/loading.gif b/ChaosDataPlayer/images/加载条.gif/loading.gif new file mode 100644 index 0000000..4117934 Binary files /dev/null and b/ChaosDataPlayer/images/加载条.gif/loading.gif differ diff --git a/ChaosDataPlayer/images/加载条.gif/loading1.gif b/ChaosDataPlayer/images/加载条.gif/loading1.gif new file mode 100644 index 0000000..d78e18b Binary files /dev/null and b/ChaosDataPlayer/images/加载条.gif/loading1.gif differ diff --git a/ChaosDataPlayer/include/gl2ps.h b/ChaosDataPlayer/include/gl2ps.h new file mode 100644 index 0000000..7818a88 --- /dev/null +++ b/ChaosDataPlayer/include/gl2ps.h @@ -0,0 +1,199 @@ +/* $Id: gl2ps.h 173 2007-05-20 15:51:51Z krischnamurti $ */ +/* + * GL2PS, an OpenGL to PostScript Printing Library + * Copyright (C) 1999-2006 Christophe Geuzaine + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of either: + * + * a) the GNU Library General Public License as published by the Free + * Software Foundation, either version 2 of the License, or (at your + * option) any later version; or + * + * b) the GL2PS License as published by Christophe Geuzaine, either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either + * the GNU Library General Public License or the GL2PS License for + * more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library in the file named "COPYING.LGPL"; + * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, + * Cambridge, MA 02139, USA. + * + * You should have received a copy of the GL2PS License with this + * library in the file named "COPYING.GL2PS"; if not, I will be glad + * to provide one. + * + * For the latest info about gl2ps, see http://www.geuz.org/gl2ps/. + * Please report all bugs and problems to . + */ + +#ifndef __GL2PS_H__ +#define __GL2PS_H__ + +#include +#include + +/* Define GL2PSDLL at compile time to build a Windows DLL */ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# if defined(_MSC_VER) +# pragma warning(disable:4115) +# if (_MSC_VER >= 1400) /* VS8 - not sure about VC7 */ +# pragma warning(disable: 4996) /* MS security enhancements */ +# endif +# endif +# include +# if defined(GL2PSDLL) +# if defined(GL2PSDLL_EXPORTS) +# define GL2PSDLL_API __declspec(dllexport) +# else +# define GL2PSDLL_API __declspec(dllimport) +# endif +# else +# define GL2PSDLL_API +# endif +#else +# define GL2PSDLL_API +#endif + +#if defined(__APPLE__) || defined(HAVE_OPENGL_GL_H) +# include +#else +# include +#endif + +/* Support for compressed PostScript/PDF/SVG and for embedded PNG + images in SVG */ + +#if defined(HAVE_ZLIB) || defined(HAVE_LIBZ) +# define GL2PS_HAVE_ZLIB +# if defined(HAVE_LIBPNG) || defined(HAVE_PNG) +# define GL2PS_HAVE_LIBPNG +# endif +#endif + +/* Version number */ + +#define GL2PS_MAJOR_VERSION 1 +#define GL2PS_MINOR_VERSION 3 +#define GL2PS_PATCH_VERSION 2 +#define GL2PS_EXTRA_VERSION "" + +#define GL2PS_VERSION (GL2PS_MAJOR_VERSION + \ + 0.01 * GL2PS_MINOR_VERSION + \ + 0.0001 * GL2PS_PATCH_VERSION) + +#define GL2PS_COPYRIGHT "(C) 1999-2006 Christophe Geuzaine (geuz@geuz.org)" + +/* Output file formats (the values and the ordering are important!) */ + +#define GL2PS_PS 0 +#define GL2PS_EPS 1 +#define GL2PS_TEX 2 +#define GL2PS_PDF 3 +#define GL2PS_SVG 4 +#define GL2PS_PGF 5 + +/* Sorting algorithms */ + +#define GL2PS_NO_SORT 1 +#define GL2PS_SIMPLE_SORT 2 +#define GL2PS_BSP_SORT 3 + +/* Message levels and error codes */ + +#define GL2PS_SUCCESS 0 +#define GL2PS_INFO 1 +#define GL2PS_WARNING 2 +#define GL2PS_ERROR 3 +#define GL2PS_NO_FEEDBACK 4 +#define GL2PS_OVERFLOW 5 +#define GL2PS_UNINITIALIZED 6 + +/* Options for gl2psBeginPage */ + +#define GL2PS_NONE 0 +#define GL2PS_DRAW_BACKGROUND (1<<0) +#define GL2PS_SIMPLE_LINE_OFFSET (1<<1) +#define GL2PS_SILENT (1<<2) +#define GL2PS_BEST_ROOT (1<<3) +#define GL2PS_OCCLUSION_CULL (1<<4) +#define GL2PS_NO_TEXT (1<<5) +#define GL2PS_LANDSCAPE (1<<6) +#define GL2PS_NO_PS3_SHADING (1<<7) +#define GL2PS_NO_PIXMAP (1<<8) +#define GL2PS_USE_CURRENT_VIEWPORT (1<<9) +#define GL2PS_COMPRESS (1<<10) +#define GL2PS_NO_BLENDING (1<<11) +#define GL2PS_TIGHT_BOUNDING_BOX (1<<12) + +/* Arguments for gl2psEnable/gl2psDisable */ + +#define GL2PS_POLYGON_OFFSET_FILL 1 +#define GL2PS_POLYGON_BOUNDARY 2 +#define GL2PS_LINE_STIPPLE 3 +#define GL2PS_BLEND 4 + +/* Text alignment (o=raster position; default mode is BL): + +---+ +---+ +---+ +---+ +---+ +---+ +-o-+ o---+ +---o + | o | o | | o | | | | | | | | | | | | + +---+ +---+ +---+ +-o-+ o---+ +---o +---+ +---+ +---+ + C CL CR B BL BR T TL TR */ + +#define GL2PS_TEXT_C 1 +#define GL2PS_TEXT_CL 2 +#define GL2PS_TEXT_CR 3 +#define GL2PS_TEXT_B 4 +#define GL2PS_TEXT_BL 5 +#define GL2PS_TEXT_BR 6 +#define GL2PS_TEXT_T 7 +#define GL2PS_TEXT_TL 8 +#define GL2PS_TEXT_TR 9 + +typedef GLfloat GL2PSrgba[4]; + +#if defined(__cplusplus) +extern "C" { +#endif + +GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, + GLint viewport[4], GLint format, GLint sort, + GLint options, GLint colormode, + GLint colorsize, GL2PSrgba *colormap, + GLint nr, GLint ng, GLint nb, GLint buffersize, + FILE *stream, const char *filename); +GL2PSDLL_API GLint gl2psEndPage(void); +GL2PSDLL_API GLint gl2psSetOptions(GLint options); +GL2PSDLL_API GLint gl2psBeginViewport(GLint viewport[4]); +GL2PSDLL_API GLint gl2psEndViewport(void); +GL2PSDLL_API GLint gl2psText(const char *str, const char *fontname, + GLshort fontsize); +GL2PSDLL_API GLint gl2psTextOpt(const char *str, const char *fontname, + GLshort fontsize, GLint align, GLfloat angle); +GL2PSDLL_API GLint gl2psSpecial(GLint format, const char *str); +GL2PSDLL_API GLint gl2psDrawPixels(GLsizei width, GLsizei height, + GLint xorig, GLint yorig, + GLenum format, GLenum type, const void *pixels); +GL2PSDLL_API GLint gl2psEnable(GLint mode); +GL2PSDLL_API GLint gl2psDisable(GLint mode); +GL2PSDLL_API GLint gl2psPointSize(GLfloat value); +GL2PSDLL_API GLint gl2psLineWidth(GLfloat value); +GL2PSDLL_API GLint gl2psBlendFunc(GLenum sfactor, GLenum dfactor); + +/* undocumented */ +GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, + const GLfloat position[3], + const unsigned char *imagemap); +GL2PSDLL_API const char *gl2psGetFileExtension(GLint format); +GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format); + +#if defined(__cplusplus) +} +#endif + +#endif /* __GL2PS_H__ */ diff --git a/ChaosDataPlayer/include/mylineplot3d.h b/ChaosDataPlayer/include/mylineplot3d.h new file mode 100644 index 0000000..8eddb94 --- /dev/null +++ b/ChaosDataPlayer/include/mylineplot3d.h @@ -0,0 +1,43 @@ +#ifndef MYLINEPLOT3D_H +#define MYLINEPLOT3D_H + +#include"qwt3d_surfaceplot.h" +#include "qwt3d_global.h" +class QWidget; + + +class QWT3D_EXPORT MyLinePlot3d : public Qwt3D::SurfacePlot +{ + Q_OBJECT + +public: + MyLinePlot3d(QWidget * parent = NULL); + ~MyLinePlot3d(); + + virtual void init(); + + virtual void createLines(); + + virtual void keyPressEvent(QKeyEvent *); + + virtual void tick(); + virtual void setCurMaxMin(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); + +private: + int myTimerId; + + int time_; + + double myxMax; + double myyMax; + double myzMax; + + double myCurxMin; + double myCuryMin; + double myCurzMin; + double myCurxMax; + double myCuryMax; + double myCurzMax; +}; + +#endif // MYLINEPLOT3D_H diff --git a/ChaosDataPlayer/include/qwt3d_autoptr.h b/ChaosDataPlayer/include/qwt3d_autoptr.h new file mode 100644 index 0000000..cb2287d --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_autoptr.h @@ -0,0 +1,75 @@ +#ifndef qwt3d_autoptr_h__2004_05_14_18_57_begin_guarded_code +#define qwt3d_autoptr_h__2004_05_14_18_57_begin_guarded_code + +namespace Qwt3D +{ + +//! Simple Auto pointer providing deep copies for raw pointer +/*! + Requirements: \n + virtual T* T::clone() const;\n + T::destroy() const; + virtual ~T() private/protected\n\n + clone() is necessary for the pointer to preserve polymorphic behaviour. + The pointer requires also heap based objects with regard to the template + argument in order to be able to get ownership and control over destruction. + */ +template +class qwt3d_ptr +{ +public: + //! Standard ctor + explicit qwt3d_ptr(T* ptr = 0) + :rawptr_(ptr) + { + } + //! Dtor (calls T::destroy) + ~qwt3d_ptr() + { + destroyRawPtr(); + } + + //! Copy ctor (calls (virtual) clone()) + qwt3d_ptr(qwt3d_ptr const& val) + { + rawptr_ = val.rawptr_->clone(); + } + + //! Assignment in the same spirit as copy ctor + qwt3d_ptr& operator=(qwt3d_ptr const& val) + { + if (this == &val) + return *this; + + destroyRawPtr(); + rawptr_ = val.rawptr_->clone(); + + return *this; + } + + //! It's a pointerlike object, isn't it ? + T* operator->() const + { + return rawptr_; + } + + //! Dereferencing + T& operator*() const + { + return *rawptr_; + } + + +private: + T* rawptr_; + void destroyRawPtr() + { + if (rawptr_) + rawptr_->destroy(); + rawptr_ = 0; + } +}; + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_autoscaler.h b/ChaosDataPlayer/include/qwt3d_autoscaler.h new file mode 100644 index 0000000..56a0c96 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_autoscaler.h @@ -0,0 +1,51 @@ +#ifndef __qwt3d_autoscaler_2003_08_18_12_05__ +#define __qwt3d_autoscaler_2003_08_18_12_05__ + +#include +#include "qwt3d_global.h" +#include "qwt3d_autoptr.h" + +namespace Qwt3D +{ + +//! ABC for autoscaler +class QWT3D_EXPORT AutoScaler +{ +friend class qwt3d_ptr; +protected: + //! Returns a new heap based object of the derived class. + virtual AutoScaler* clone() const = 0; + //! To implement from subclasses + virtual int execute(double& a, double& b, double start, double stop, int ivals) = 0; + virtual ~AutoScaler(){} + +private: + void destroy() const {delete this;} //!< Used by qwt3d_ptr +}; + +//! Automatic beautifying of linear scales +class QWT3D_EXPORT LinearAutoScaler : public AutoScaler +{ +friend class LinearScale; +protected: + LinearAutoScaler(); + explicit LinearAutoScaler(std::vector& mantisses); + //! Returns a new heap based object utilized from qwt3d_ptr + AutoScaler* clone() const {return new LinearAutoScaler(*this);} + int execute(double& a, double& b, double start, double stop, int ivals); + +private: + + double start_, stop_; + int intervals_; + + void init(double start, double stop, int ivals); + double anchorvalue(double start, double mantisse, int exponent); + int segments(int& l_intervals, int& r_intervals, double start, double stop, double anchor, double mantissa, int exponent); + std::vector mantissi_; +}; + +} // ns + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_axis.h b/ChaosDataPlayer/include/qwt3d_axis.h new file mode 100644 index 0000000..52d6243 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_axis.h @@ -0,0 +1,131 @@ +#ifndef __AXIS_H__ +#define __AXIS_H__ + +#include "qwt3d_autoptr.h" +#include "qwt3d_label.h" +#include "qwt3d_scale.h" +#include "qwt3d_autoscaler.h" + +namespace Qwt3D +{ + +//! Autoscalable axis with caption. +/*! + Axes are highly customizable especially in terms + of labeling and scaling. +*/ +class QWT3D_EXPORT Axis : public Drawable +{ + +public: + + Axis(); //!< Constructs standard axis + Axis(Qwt3D::Triple beg, Qwt3D::Triple end); //!< Constructs a new axis with specified limits + virtual ~Axis(); // dtor + + virtual void draw(); //!< Draws axis + + void setPosition(const Qwt3D::Triple& beg, const Qwt3D::Triple& end); //!< Positionate axis + void position(Qwt3D::Triple& beg, Qwt3D::Triple& end) const {beg = beg_; end = end_;} //!< Returns axis' position + Qwt3D::Triple begin() const { return beg_; } //!< Returns axis' beginning position + Qwt3D::Triple end() const { return end_; } //!< Returns axis' ending position + double length() const { return (end_-beg_).length(); } //!< Returns axis' length + + void setTicLength(double majorl, double minorl); //!< Sets tics lengths in world coordinates + //! Returns tics lengths + void ticLength(double& majorl, double& minorl) const {majorl = lmaj_; minorl = lmin_;} + void setTicOrientation(double tx, double ty, double tz); //!< Sets tic orientation + void setTicOrientation(const Qwt3D::Triple& val); //!< Same function as above + Qwt3D::Triple ticOrientation() const { return orientation_;} //!< Returns tic orientation + void setSymmetricTics( bool b) { symtics_ = b;} //!< Sets two-sided tics (default is false) + + //! Sets font for axis label + void setLabelFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + void setLabelFont(QFont const& font); //!< Sets font for axis label + QFont const& labelFont() const {return labelfont_;} //!< Returns current label font + + void setLabelString(QString const& name); //!< Sets label content + void setLabelPosition(const Qwt3D::Triple& pos, Qwt3D::ANCHOR); + void setLabelColor(Qwt3D::RGBA col); + void setLabel(bool d) {drawLabel_ = d;} //!< Turns label drawing on or off + void adjustLabel(int val) {labelgap_ = val;} //!< Shifts label in device coordinates dependent on anchor; + + void setScaling(bool d) {drawTics_ = d;} //!< Turns scale drawing on or off + bool scaling() const {return drawTics_;} //!< Returns, if scale drawing is on or off + void setScale(Qwt3D::SCALETYPE); + void setScale(Scale* item); + void setNumbers(bool d) {drawNumbers_ = d;} //!< Turns number drawing on or off + bool numbers() const {return drawNumbers_;} //!< Returns, if number drawing is on or off + void setNumberColor(Qwt3D::RGBA col); //!< Sets the color for axes numbers + Qwt3D::RGBA numberColor() const {return numbercolor_;} //!< Returns the color for axes numbers + //! Sets font for numbering + void setNumberFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + void setNumberFont(QFont const&); //!< Overloaded member, works like the above function + QFont const& numberFont() const {return numberfont_;} //!< Returns current numbering font + void setNumberAnchor(Qwt3D::ANCHOR a) { scaleNumberAnchor_ = a;} //!< Sets anchor position for numbers + void adjustNumbers(int val) {numbergap_ = val;} //!< Shifts axis numbers in device coordinates dependent on anchor; + + void setAutoScale(bool val = true) {autoscale_ = val;} //!< Turns Autoscaling on or off + bool autoScale() const { return autoscale_;} //!< actual Autoscaling mode + + void setMajors(int val); //!< Requests major intervals (maybe changed, if autoscaling is present) + void setMinors(int val); //!< Requests minor intervals + int majors() const { return majorintervals_; } //!< Returns number of major intervals + int minors() const { return minorintervals_; } //!< Returns number of minor intervals + Qwt3D::TripleField const& majorPositions() const {return majorpos_;} //!< Returns positions for actual major tics (also if invisible) + Qwt3D::TripleField const& minorPositions() const {return minorpos_;} //!< Returns positions for actual minor tics (also if invisible) + + //! Sets line width for axis components + void setLineWidth(double val, double majfac = 0.9, double minfac = 0.5); + double lineWidth() const { return lineWidth_;} //!< Returns line width for axis body + double majLineWidth() const { return majLineWidth_;} //!< Returns Line width for major tics + double minLineWidth() const { return minLineWidth_;} //!< Returns Line width for minor tics + + void setLimits(double start, double stop) {start_=start; stop_=stop;} //!< Sets interval + void limits(double& start, double& stop) const {start = start_; stop = stop_;} //!< Returns axis interval + void recalculateTics(); //!< Enforces recalculation of ticmark positions + + +private: + + void init(); + void drawBase(); + void drawTics(); + void drawTicLabel(Qwt3D::Triple Pos, int mtic); + Qwt3D::Triple drawTic(Qwt3D::Triple nadir, double length); + void drawLabel(); + bool prepTicCalculation(Triple& startpoint); + + Qwt3D::Triple biggestNumberString(); + + + Qwt3D::ANCHOR scaleNumberAnchor_; + Qwt3D::Label label_; + std::vector markerLabel_; + + Qwt3D::Triple beg_, end_; + Qwt3D::TripleField majorpos_, minorpos_; //! vectors, holding major resp. minor tic positions; + + Qwt3D::Triple ncube_beg_, ncube_end_; //!< enclosing parallelepiped for axis numbering + + double start_, stop_, autostart_, autostop_; + double lmaj_, lmin_; + Qwt3D::Triple orientation_; + + int majorintervals_, minorintervals_; + + double lineWidth_, majLineWidth_, minLineWidth_; + bool symtics_; + bool drawNumbers_, drawTics_, drawLabel_; + bool autoscale_; + QFont numberfont_, labelfont_; + Qwt3D::RGBA numbercolor_; + + int numbergap_, labelgap_; + + Qwt3D::qwt3d_ptr scale_; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_color.h b/ChaosDataPlayer/include/qwt3d_color.h new file mode 100644 index 0000000..0c195fc --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_color.h @@ -0,0 +1,63 @@ +#ifndef __COLORGENERATOR_H__ +#define __COLORGENERATOR_H__ + +#include +#include "qwt3d_global.h" +#include "qwt3d_types.h" + +namespace Qwt3D +{ + +//! Abstract base class for color functors +/*! +Use your own color model by providing an implementation of operator()(double x, double y, double z). +Colors destructor has been declared \c protected, in order to use only heap based objects. Plot3D +will handle the objects destruction. +See StandardColor for an example +*/ +class QWT3D_EXPORT Color +{ +public: + virtual Qwt3D::RGBA operator()(double x, double y, double z) const = 0; //!< Implement your color model here + virtual Qwt3D::RGBA operator()(Qwt3D::Triple const& t) const {return this->operator()(t.x,t.y,t.z);} + //! Should create a color vector usable by ColorLegend. The default implementation returns his argument + virtual Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec) { return vec; } + + void destroy() const { delete this;} + +protected: + virtual ~Color(){} //!< Allow heap based objects only +}; + + + +class Plot3D; +//! Standard color model for Plot3D - implements the data driven operator()(double x, double y, double z) +/*! +The class has a ColorVector representing z values, which will be used by operator()(double x, double y, double z) +*/ +class QWT3D_EXPORT StandardColor : public Color +{ +public: + //! Initializes with data and set up a ColorVector with a size of 100 z values (default); + explicit StandardColor(Qwt3D::Plot3D* data, unsigned size = 100); + Qwt3D::RGBA operator()(double x, double y, double z) const; //!< Receives z-dependend color from ColorVector + void setColorVector(Qwt3D::ColorVector const& cv); + void reset(unsigned size=100); //!< Resets the standard colors; + void setAlpha(double a); //!< Sets unitary alpha value for all colors + /** + \brief Creates color vector + + Creates a color vector used by ColorLegend. This is essentially a copy from the internal used vector. + \return The vector created + */ + Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec) {vec = colors_; return vec;} + +protected: + Qwt3D::ColorVector colors_; + Qwt3D::Plot3D* data_; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_colorlegend.h b/ChaosDataPlayer/include/qwt3d_colorlegend.h new file mode 100644 index 0000000..8e06730 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_colorlegend.h @@ -0,0 +1,77 @@ +#ifndef __PLANE_H__ +#define __PLANE_H__ + +#include "qwt3d_global.h" +#include "qwt3d_drawable.h" +#include "qwt3d_axis.h" +#include "qwt3d_color.h" + +namespace Qwt3D +{ + +//! A flat color legend +/** + The class visualizes a ColorVector together with a scale (axis) and a caption. ColorLegends are vertical + or horizontal +*/ +class QWT3D_EXPORT ColorLegend : public Drawable +{ + +public: + + //! Possible anchor points for caption and axis + enum SCALEPOSITION + { + Top, //!< scale on top + Bottom, //!< scale on bottom + Left, //!< scale left + Right //!< scale right + }; + + //! Orientation of the legend + enum ORIENTATION + { + BottomTop, //!< Positionate the legend vertically, the lowest color index is on the bottom + LeftRight //!< Positionate the legend horizontally, the lowest color index is on left side + }; + + ColorLegend(); //!< Standard constructor + + void draw(); //!< Draws the object. You should not use this explicitely - the function is called by updateGL(). + + void setRelPosition(Qwt3D::Tuple relMin, Qwt3D::Tuple relMax); //!< Sets the relative position of the legend inside widget + void setOrientation(ORIENTATION, SCALEPOSITION); //!< Sets legend orientation and scale position + void setLimits(double start, double stop); //!< Sets the limit of the scale. + void setMajors(int); //!< Sets scale major tics. + void setMinors(int); //!< Sets scale minor tics. + void drawScale(bool val) { showaxis_ = val; } //!< Sets whether a scale will be drawn. + void drawNumbers(bool val) { axis_.setNumbers(val); } //!< Sets whether the scale will have scale numbers. + void setAutoScale(bool val); //!< Sets, whether the axis is autoscaled or not. + void setScale(Qwt3D::Scale *scale); //!< Sets another scale + void setScale(Qwt3D::SCALETYPE); //!< Sets one of the predefined scale types + + void setTitleString(QString const& s); //!< Sets the legends caption string. + + //! Sets the legends caption font. + void setTitleFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + + Qwt3D::ColorVector colors; //!< The color vector + +private: + + Qwt3D::Label caption_; + Qwt3D::ParallelEpiped geometry() const { return pe_;} + void setGeometryInternal(); + + Qwt3D::ParallelEpiped pe_; + Qwt3D::Tuple relMin_, relMax_; + Qwt3D::Axis axis_; + SCALEPOSITION axisposition_; + ORIENTATION orientation_; + + bool showaxis_; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_coordsys.h b/ChaosDataPlayer/include/qwt3d_coordsys.h new file mode 100644 index 0000000..43c36f3 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_coordsys.h @@ -0,0 +1,100 @@ +#ifndef __COORDSYS_H__ +#define __COORDSYS_H__ + +#include "qwt3d_axis.h" +#include "qwt3d_colorlegend.h" + +namespace Qwt3D +{ + +//! A coordinate system with different styles (BOX, FRAME) +class QWT3D_EXPORT CoordinateSystem : public Drawable +{ + +public: + explicit CoordinateSystem(Qwt3D::Triple blb = Qwt3D::Triple(0,0,0), Qwt3D::Triple ftr = Qwt3D::Triple(0,0,0), Qwt3D::COORDSTYLE = Qwt3D::BOX); + ~CoordinateSystem(); + + void init(Qwt3D::Triple beg = Qwt3D::Triple(0,0,0), Qwt3D::Triple end = Qwt3D::Triple(0,0,0)); + //! Set style for the coordinate system (NOCOORD, FRAME or BOX) + void setStyle(Qwt3D::COORDSTYLE s, Qwt3D::AXIS frame_1 = Qwt3D::X1, + Qwt3D::AXIS frame_2 = Qwt3D::Y1, + Qwt3D::AXIS frame_3 = Qwt3D::Z1); + Qwt3D::COORDSTYLE style() const { return style_;} //!< Return style oft the coordinate system + void setPosition(Qwt3D::Triple first, Qwt3D::Triple second); //!< first == front_left_bottom, second == back_right_top + + void setAxesColor(Qwt3D::RGBA val); //!< Set common color for all axes + //! Set common font for all axis numberings + void setNumberFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + //! Set common font for all axis numberings + void setNumberFont(QFont const& font); + //! Set common color for all axis numberings + void setNumberColor(Qwt3D::RGBA val); + void setStandardScale(); //!< Sets an linear axis with real number items + + void adjustNumbers(int val); //!< Fine tunes distance between axis numbering and axis body + void adjustLabels(int val); //!< Fine tunes distance between axis label and axis body + + //! Sets color for the grid lines + void setGridLinesColor(Qwt3D::RGBA val) {gridlinecolor_ = val;} + + //! Set common font for all axis labels + void setLabelFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + //! Set common font for all axis labels + void setLabelFont(QFont const& font); + //! Set common color for all axis labels + void setLabelColor(Qwt3D::RGBA val); + + //! Set line width for tic marks and axes + void setLineWidth(double val, double majfac = 0.9, double minfac = 0.5); + //! Set length for tic marks + void setTicLength(double major, double minor); + + //! Switch autoscaling of axes + void setAutoScale(bool val = true); + + Qwt3D::Triple first() const { return first_;} + Qwt3D::Triple second() const { return second_;} + + void setAutoDecoration(bool val = true) {autodecoration_ = val;} + bool autoDecoration() const { return autodecoration_;} + + void setLineSmooth(bool val = true) {smooth_ = val;} //!< draw smooth axes + bool lineSmooth() const {return smooth_;} //!< smooth axes ? + + void draw(); + + //! Defines whether a grid between the major and/or minor tics should be drawn + void setGridLines(bool majors, bool minors, int sides = Qwt3D::NOSIDEGRID); + int grids() const {return sides_;} //!< Returns grids switched on + + //! The vector of all12 axes - use them to set axis properties individually. + std::vector axes; + + +private: + void destroy(); + + Qwt3D::Triple first_, second_; + Qwt3D::COORDSTYLE style_; + + Qwt3D::RGBA gridlinecolor_; + + bool smooth_; + + void chooseAxes(); + void autoDecorateExposedAxis(Axis& ax, bool left); + void drawMajorGridLines(); //!< Draws a grid between the major tics on the site + void drawMinorGridLines(); //!< Draws a grid between the minor tics on the site + void drawMajorGridLines(Qwt3D::Axis&, Qwt3D::Axis&); //! Helper + void drawMinorGridLines(Qwt3D::Axis&, Qwt3D::Axis&); //! Helper + void recalculateAxesTics(); + + bool autodecoration_; + bool majorgridlines_, minorgridlines_; + int sides_; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_drawable.h b/ChaosDataPlayer/include/qwt3d_drawable.h new file mode 100644 index 0000000..ebad96d --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_drawable.h @@ -0,0 +1,66 @@ +#ifndef __DRAWABLE_H__ +#define __DRAWABLE_H__ + + +#include +#include "qwt3d_global.h" +#include "qwt3d_types.h" +#include "qwt3d_io_gl2ps.h" + +namespace Qwt3D +{ + +//! ABC for Drawables +class QWT3D_EXPORT Drawable +{ + +public: + + virtual ~Drawable() = 0; + + virtual void draw(); + + virtual void saveGLState(); + virtual void restoreGLState(); + + void attach(Drawable*); + void detach(Drawable*); + void detachAll(); + + virtual void setColor(double r, double g, double b, double a = 1); + virtual void setColor(Qwt3D::RGBA rgba); + Qwt3D::Triple relativePosition(Qwt3D::Triple rel); + +protected: + + Qwt3D::RGBA color; + void Enable(GLenum what, GLboolean val); + Qwt3D::Triple ViewPort2World(Qwt3D::Triple win, bool* err = 0); + Qwt3D::Triple World2ViewPort(Qwt3D::Triple obj, bool* err = 0); + + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + GLint viewport[4]; + + +private: + + GLboolean ls; + GLboolean pols; + GLint polmode[2]; + GLfloat lw; + GLint blsrc, bldst; + GLdouble col[4]; + GLint pattern, factor; + GLboolean sallowed; + GLboolean tex2d; + GLint matrixmode; + GLfloat poloffs[2]; + GLboolean poloffsfill; + + std::list dlist; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_enrichment.h b/ChaosDataPlayer/include/qwt3d_enrichment.h new file mode 100644 index 0000000..25d7a32 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_enrichment.h @@ -0,0 +1,66 @@ +#ifndef qwt3d_enrichment_h__2004_02_23_19_24_begin_guarded_code +#define qwt3d_enrichment_h__2004_02_23_19_24_begin_guarded_code + +#include "qwt3d_global.h" +#include "qwt3d_types.h" + +namespace Qwt3D +{ + +class Plot3D; + + +//! Abstract base class for data dependent visible user objects +/** +Enrichments provide a framework for user defined OPenGL objects. The base class has a pure virtuell +function clone(). 2 additional functions are per default empty and could also get a new implementation +in derived classes. They can be used for initialization issues or actions not depending on the related +primitive. +*/ +class QWT3D_EXPORT Enrichment +{ +public: + enum TYPE{ + VERTEXENRICHMENT, + EDGEENRICHMENT, + FACEENRICHMENT, + VOXELENRICHMENT + }; //!< Type of the Enrichment - only VERTEXENRICHMENT's are defined at this moment. + + Enrichment() : plot(0) {} + virtual ~Enrichment(){} + virtual Enrichment* clone() const = 0; //!< The derived class should give back a new Derived(something) here + virtual void drawBegin(){}; //!< Empty per default. Can be overwritten. + virtual void drawEnd(){}; //!< Empty per default. Can be overwritten. + virtual void assign(Plot3D const& pl) {plot = &pl;} //!< Assign to existent plot; + virtual TYPE type() const = 0; //!< Overwrite + virtual void draw() + { + + } + +protected: + const Plot3D* plot; +}; + +//! Abstract base class for vertex dependent visible user objects +/** +VertexEnrichments introduce a specialized draw routine for vertex dependent data. +draw() is called, when the Plot realizes its internal OpenGL data representation +for every Vertex associated to his argument. +*/ +class QWT3D_EXPORT VertexEnrichment : public Enrichment +{ +public: + + VertexEnrichment() : Qwt3D::Enrichment() {} + virtual Enrichment* clone() const = 0; //!< The derived class should give back a new Derived(something) here + virtual void draw(Qwt3D::Triple const&) = 0; //!< Overwrite this + virtual TYPE type() const {return Qwt3D::Enrichment::VERTEXENRICHMENT;} //!< This gives VERTEXENRICHMENT +}; + +// todo EdgeEnrichment, FaceEnrichment, VoxelEnrichment etc. + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_enrichment_std.h b/ChaosDataPlayer/include/qwt3d_enrichment_std.h new file mode 100644 index 0000000..520c0a1 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_enrichment_std.h @@ -0,0 +1,157 @@ +#ifndef qwt3d_enrichment_std_h__2004_02_23_19_25_begin_guarded_code +#define qwt3d_enrichment_std_h__2004_02_23_19_25_begin_guarded_code + +#include "qwt3d_enrichment.h" + +namespace Qwt3D +{ + +class Plot3D; + +//! The Cross Hair Style +class QWT3D_EXPORT CrossHair : public VertexEnrichment +{ +public: + CrossHair(); + CrossHair(double rad, double linewidth, bool smooth, bool boxed); + + Qwt3D::Enrichment* clone() const {return new CrossHair(*this);} + + void configure(double rad, double linewidth, bool smooth, bool boxed); + void drawBegin(); + void drawEnd(); + void draw(Qwt3D::Triple const&); + +private: + bool boxed_, smooth_; + double linewidth_, radius_; + GLboolean oldstate_; +}; + +//! The Point Style +class QWT3D_EXPORT Dot : public VertexEnrichment +{ +public: + Dot(); + Dot(double pointsize, bool smooth); + + Qwt3D::Enrichment* clone() const {return new Dot(*this);} + + void configure(double pointsize, bool smooth); + void drawBegin(); + void drawEnd(); + void draw(Qwt3D::Triple const&); + +private: + bool smooth_; + double pointsize_; + GLboolean oldstate_; +}; + + +class QWT3D_EXPORT Line3D: public VertexEnrichment +{ +public: + Line3D(); + Line3D(double thick,bool smooth); + Qwt3D::Enrichment * clone() const{ return new Line3D(*this);} + + void configure(double thick, bool smooth); + void drawBegin(); + void drawEnd(); + virtual void draw(Qwt3D::Triple const&); + + virtual void draw(); + + //mine + virtual void rdraw(); + + virtual void add(Qwt3D::Triple const & t); + virtual void setLineColor(RGBA color); + virtual void clear() + { + lineData.clear(); + myColorMap.clear(); + } + +// virtual void setLineColor(int startIndex,RGBA color); +// virtual RGBA getColor(int pointIndex); + + +private: + bool smooth_; + double lineThick; + GLboolean oldstate_; + + std::vector lineData; + + RGBA rgba; + std::map myColorMap; + +}; +//! The Cone Style +class QWT3D_EXPORT Cone : public VertexEnrichment +{ +public: + Cone(); + Cone(double rad, unsigned quality); + ~Cone(); + + Qwt3D::Enrichment* clone() const {return new Cone(*this);} + + void configure(double rad, unsigned quality); + void draw(Qwt3D::Triple const&); + +private: + GLUquadricObj *hat; + GLUquadricObj *disk; + unsigned quality_; + double radius_; + GLboolean oldstate_; +}; + +//! 3D vector field. +/** + The class encapsulates a vector field including his OpenGL representation as arrow field. + The arrows can be configured in different aspects (color, shape, painting quality). + +*/ +class QWT3D_EXPORT Arrow : public VertexEnrichment +{ +public: + + Arrow(); + ~Arrow(); + + Qwt3D::Enrichment* clone() const {return new Arrow(*this);} + + void configure(int segs, double relconelength, double relconerad, double relstemrad); + void setQuality(int val) {segments_ = val;} //!< Set the number of faces for the arrow + void draw(Qwt3D::Triple const&); + + void setTop(Qwt3D::Triple t){top_ = t;} + void setColor(Qwt3D::RGBA rgba) {rgba_ = rgba;} + +private: + + GLUquadricObj *hat; + GLUquadricObj *disk; + GLUquadricObj *base; + GLUquadricObj *bottom; + GLboolean oldstate_; + + double calcRotation(Qwt3D::Triple& axis, Qwt3D::FreeVector const& vec); + + int segments_; + double rel_cone_length; + + double rel_cone_radius; + double rel_stem_radius; + + Qwt3D::Triple top_; + Qwt3D::RGBA rgba_; +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_function.h b/ChaosDataPlayer/include/qwt3d_function.h new file mode 100644 index 0000000..c87939d --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_function.h @@ -0,0 +1,41 @@ +#ifndef qwt3d_function_h__2004_03_05_13_51_begin_guarded_code +#define qwt3d_function_h__2004_03_05_13_51_begin_guarded_code + +#include "qwt3d_gridmapping.h" + +namespace Qwt3D +{ + +class SurfacePlot; + +//! Abstract base class for mathematical functions +/** + A Function encapsulates a mathematical function with rectangular domain. The user has to adapt the pure virtual operator() + to get a working object. Also, the client code should call setDomain, setMesh and create for reasonable operating conditions. +*/ +class QWT3D_EXPORT Function : public GridMapping +{ + +public: + + Function(); //!< Constructs Function object w/o assigned SurfacePlot. + explicit Function(Qwt3D::SurfacePlot& plotWidget); //!< Constructs Function object and assigns a SurfacePlot + explicit Function(Qwt3D::SurfacePlot* plotWidget); //!< Constructs Function object and assigns a SurfacePlot + virtual double operator()(double x, double y) = 0; //!< Overwrite this. + + void setMinZ(double val); //!< Sets minimal z value. + void setMaxZ(double val); //!< Sets maximal z value. + + //! Assigns a new SurfacePlot and creates a data representation for it. + virtual bool create(Qwt3D::SurfacePlot& plotWidget); + //! Creates data representation for the actual assigned SurfacePlot. + virtual bool create(); + //! Assigns the object to another widget. To see the changes, you have to call this function before create(). + void assign(Qwt3D::SurfacePlot& plotWidget); + //! Assigns the object to another widget. To see the changes, you have to call this function before create(). + void assign(Qwt3D::SurfacePlot* plotWidget); +}; + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_global.h b/ChaosDataPlayer/include/qwt3d_global.h new file mode 100644 index 0000000..eb66a44 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_global.h @@ -0,0 +1,58 @@ +#ifndef QWT3D_GLOBAL_H +#define QWT3D_GLOBAL_H + +#include +#if QT_VERSION < 0x040000 +#include +#endif + +#define QWT3D_MAJOR_VERSION 0 +#define QWT3D_MINOR_VERSION 2 +#define QWT3D_PATCH_VERSION 6 + +// +// Create Qwt3d DLL if QWT3D_DLL is defined (Windows only) +// + +#if defined(Q_WS_WIN) + #if defined(_MSC_VER) /* MSVC Compiler */ + #pragma warning(disable: 4251) // dll interface required for stl templates + //pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data + #pragma warning(disable: 4786) // truncating debug info after 255 characters + #pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated + #if (_MSC_VER >= 1400) /* VS8 - not sure about VC7 */ + #pragma warning(disable: 4996) /* MS security enhancements */ + #endif + #endif + + #if defined(QWT3D_NODLL) + #undef QWT3D_MAKEDLL + #undef QWT3D_DLL + #undef QWT3D_TEMPLATEDLL + #endif + + #ifdef QWT3D_DLL + #if defined(QWT3D_MAKEDLL) /* create a Qwt3d DLL library */ + #undef QWT3D_DLL + #define QWT3D_EXPORT __declspec(dllexport) + #define QWT3D_TEMPLATEDLL + #endif + #endif + + #if defined(QWT3D_DLL) /* use a Qwt3d DLL library */ + #define QWT3D_EXPORT __declspec(dllimport) + #define QWT3D_TEMPLATEDLL + #endif + +#else // ! Q_WS_WIN + #undef QWT3D_MAKEDLL /* ignore these for other platforms */ + #undef QWT3D_DLL + #undef QWT3D_TEMPLATEDLL +#endif + +#ifndef QWT3D_EXPORT + #define QWT3D_EXPORT +#endif + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_graphplot.h b/ChaosDataPlayer/include/qwt3d_graphplot.h new file mode 100644 index 0000000..9a6382c --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_graphplot.h @@ -0,0 +1,24 @@ +#ifndef qwt3d_graphplot_h__2004_03_06_01_57_begin_guarded_code +#define qwt3d_graphplot_h__2004_03_06_01_57_begin_guarded_code + +#include "qwt3d_plot.h" + +namespace Qwt3D +{ + +//! TODO +class QWT3D_EXPORT GraphPlot : public Plot3D +{ +// Q_OBJECT + +public: + GraphPlot( QWidget* parent = 0, const char* name = 0 ); + +protected: + virtual void createData() = 0; +}; + +} // ns + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_gridmapping.h b/ChaosDataPlayer/include/qwt3d_gridmapping.h new file mode 100644 index 0000000..7b9700b --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_gridmapping.h @@ -0,0 +1,34 @@ +#ifndef qwt3d_gridmapping_h__2004_03_06_12_31_begin_guarded_code +#define qwt3d_gridmapping_h__2004_03_06_12_31_begin_guarded_code + +#include "qwt3d_mapping.h" + +namespace Qwt3D +{ + +class SurfacePlot; + + +//! Abstract base class for mappings acting on rectangular grids +/** + +*/ +class QWT3D_EXPORT GridMapping : public Mapping +{ +public: + GridMapping(); //!< Constructs GridMapping object w/o assigned SurfacePlot. + + void setMesh(unsigned int columns, unsigned int rows); //!< Sets number of rows and columns. + void setDomain(double minu, double maxu, double minv, double maxv); //!< Sets u-v domain boundaries. + void restrictRange(Qwt3D::ParallelEpiped const&); //!< Restrict the mappings range to the parallelepiped + +protected: + Qwt3D::ParallelEpiped range_p; + Qwt3D::SurfacePlot* plotwidget_p; + unsigned int umesh_p, vmesh_p; + double minu_p, maxu_p, minv_p, maxv_p; +}; + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_helper.h b/ChaosDataPlayer/include/qwt3d_helper.h new file mode 100644 index 0000000..9596483 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_helper.h @@ -0,0 +1,36 @@ +#ifndef __HELPER_H__ +#define __HELPER_H__ + +#include +#include +#include +#include + +namespace +{ + inline double Min_(double a, double b) + { + return (a0) ? int(d+0.5) : int(d-0.5); +} + + +} //ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_io.h b/ChaosDataPlayer/include/qwt3d_io.h new file mode 100644 index 0000000..9512e1d --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_io.h @@ -0,0 +1,141 @@ +#ifndef __qwt3d_io_2003_07_04_23_27__ +#define __qwt3d_io_2003_07_04_23_27__ + +#include +#include + +#include +#include +#include "qwt3d_global.h" + +namespace Qwt3D +{ + +class Plot3D; +/** +IO provides a generic interface for standard and user written I/O handlers. +It also provides functionality for the registering of such handlers in the +framework.\n +The interface mimics roughly Qt's QImageIO functions for defining +image input/output functions. +*/ +class QWT3D_EXPORT IO +{ + +public: + /*! + The function type that can be processed by the define... members. + An extension is the IO::Functor. + */ + typedef bool (*Function)(Plot3D*, QString const& fname); + + + /*! + This class gives more flexibility in implementing + userdefined IO handlers than the simple IO::Function type. + */ + class Functor + { + public: + virtual ~Functor() {} + /*! Must clone the content of *this for an object of a derived class with + \c new and return the pointer. Like operator() the predefined Functors + hide this function from the user, still allowing IO access + (friend declaration) + */ + virtual Functor* clone() const = 0; + /*! The workhorse of the user-defined implementation. Eventually, the + framework will call this operator. + */ + virtual bool operator()(Plot3D* plot, QString const& fname) = 0; + }; + + static bool defineInputHandler( QString const& format, Function func); + static bool defineOutputHandler( QString const& format, Function func); + static bool defineInputHandler( QString const& format, Functor const& func); + static bool defineOutputHandler( QString const& format, Functor const& func); + static bool save(Plot3D*, QString const& fname, QString const& format); + static bool load(Plot3D*, QString const& fname, QString const& format); + static QStringList inputFormatList(); + static QStringList outputFormatList(); + static Functor* outputHandler(QString const& format); + static Functor* inputHandler(QString const& format); + +private: + IO(){} + + //! Lightweight Functor encapsulating an IO::Function + class Wrapper : public Functor + { + public: + //! Performs actual input + Functor* clone() const { return new Wrapper(*this); } + //! Creates a Wrapper object from a function pointer + explicit Wrapper(Function h) : hdl(h) {} + //! Returns a pointer to the wrapped function + bool operator()(Plot3D* plot, QString const& fname) + { + return (hdl) ? (*hdl)(plot, fname) : false; + } + private: + Function hdl; + }; + + struct Entry + { + Entry(); + ~Entry(); + + Entry(Entry const& e); + void operator=(Entry const& e); + + Entry(QString const& s, Functor const& f); + Entry(QString const& s, Function f); + + QString fmt; + Functor* iofunc; + }; + + struct FormatCompare + { + explicit FormatCompare(Entry const& e); + bool operator() (Entry const& e); + + Entry e_; + }; + + struct FormatCompare2 + { + explicit FormatCompare2(QString s); + bool operator() (Entry const& e); + + QString s_; + }; + + typedef std::vector Container; + typedef Container::iterator IT; + + static bool add_unique(Container& l, Entry const& e); + static IT find(Container& l, QString const& fmt); + static Container& rlist(); + static Container& wlist(); + static void setupHandler(); +}; + +//! Provides Qt's Pixmap output facilities +class QWT3D_EXPORT PixmapWriter : public IO::Functor +{ +friend class IO; +public: + PixmapWriter() : quality_(-1) {} + void setQuality(int val); +private: + IO::Functor* clone() const {return new PixmapWriter(*this);} + bool operator()(Plot3D* plot, QString const& fname); + QString fmt_; + int quality_; +}; + +} //ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_io_gl2ps.h b/ChaosDataPlayer/include/qwt3d_io_gl2ps.h new file mode 100644 index 0000000..f79489f --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_io_gl2ps.h @@ -0,0 +1,91 @@ +#ifndef qwt3d_io_gl2ps_h__2004_05_07_01_16_begin_guarded_code +#define qwt3d_io_gl2ps_h__2004_05_07_01_16_begin_guarded_code + +#include + +#if QT_VERSION < 0x040000 +#include +#else +#include +#endif + +#include "qwt3d_types.h" +#include "qwt3d_io.h" + +namespace Qwt3D +{ + +//! Provides EPS, PS, PDF and TeX output +/*! + + */ +class QWT3D_EXPORT VectorWriter : public IO::Functor +{ +friend class IO; + +public: + //! The possible output formats for the text parts of the scene + enum TEXTMODE + { + PIXEL, //!< All text will be converted to pixmaps + NATIVE, //!< Text output in the native output format + TEX //!< Text output in additional LaTeX file as an overlay + }; + //! The possible behaviour for landscape settings + enum LANDSCAPEMODE + { + ON, //!< Landscape mode on + OFF, //!< Landscape mode off + AUTO //!< The output orientation depends on the plot widgets aspect ratio (default) + }; + + //! The possible sorting types which are translated in gl2ps types + enum SORTMODE + { + NOSORT, //!< No sorting at all + SIMPLESORT, //!< A more simple (yet quicker) algorithm (default) + BSPSORT //!< BSP SORT (best and slow!) + }; + + VectorWriter(); + + void setLandscape(LANDSCAPEMODE val) {landscape_ = val;} //!< Sets landscape mode. + LANDSCAPEMODE landscape() const {return landscape_;} //!< Returns the current landscape mode + + void setTextMode(TEXTMODE val, QString fname = ""); + TEXTMODE textMode() const {return textmode_;} //!< Return current text output mode. + + + //! Sets one of the SORTMODE sorting modes. + void setSortMode(SORTMODE val) {sortmode_ = val;} + SORTMODE sortMode() const {return sortmode_;} //!< Returns gl2ps sorting type. + //! Turns compressed output on or off (no effect if zlib support is not available) + void setCompressed(bool val); + //! Returns compression mode (always false if zlib support has not been set) + bool compressed() const {return compressed_;} + + bool setFormat(QString const& format); + +private: + IO::Functor* clone() const; + bool operator()(Plot3D* plot, QString const& fname); + + GLint gl2ps_format_; + bool formaterror_; + bool compressed_; + SORTMODE sortmode_; + LANDSCAPEMODE landscape_; + TEXTMODE textmode_; + QString texfname_; +}; + +GLint setDeviceLineWidth(GLfloat val); +GLint setDevicePointSize(GLfloat val); +GLint drawDevicePixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLint drawDeviceText(const char* str, const char* fontname, int fontsize, Qwt3D::Triple pos, Qwt3D::RGBA rgba, Qwt3D::ANCHOR align, double gap); +void setDevicePolygonOffset(GLfloat factor, GLfloat units); + + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_io_reader.h b/ChaosDataPlayer/include/qwt3d_io_reader.h new file mode 100644 index 0000000..1b991ee --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_io_reader.h @@ -0,0 +1,35 @@ +#ifndef qwt3d_reader_h__2004_03_07_14_03_begin_guarded_code +#define qwt3d_reader_h__2004_03_07_14_03_begin_guarded_code + +#include "qwt3d_io.h" + +namespace Qwt3D +{ + +/*! +Functor for reading of native files containing grid data. +As a standart input functor associated with "mes" and "MES" +file extensions. +*/ +class QWT3D_EXPORT NativeReader : public IO::Functor +{ +friend class IO; + +public: + NativeReader(); + +private: + //! Provides new NativeReader object. + IO::Functor* clone() const{return new NativeReader(*this);} + //! Performs actual input + bool operator()(Plot3D* plot, QString const& fname); + static const char* magicstring; + double minz_, maxz_; + bool collectInfo(FILE*& file, QString const& fname, unsigned& xmesh, unsigned& ymesh, + double& minx, double& maxx, double& miny, double& maxy); +}; + + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_label.h b/ChaosDataPlayer/include/qwt3d_label.h new file mode 100644 index 0000000..3fffc59 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_label.h @@ -0,0 +1,80 @@ +#ifndef __LABELPIXMAP_H__ +#define __LABELPIXMAP_H__ + +#include +#include +#include +#include +#include + +#include "qwt3d_drawable.h" + +namespace Qwt3D +{ + +//! A Qt string or an output device dependent string +class QWT3D_EXPORT Label : public Drawable +{ + +public: + + Label(); + //! Construct label and initialize with font + Label(const QString & family, int pointSize, int weight = QFont::Normal, bool italic = false); + + //! Sets the labels font + void setFont(QString const& family, int pointSize, int weight = QFont::Normal, bool italic = false); + + void adjust(int gap); //!< Fine tunes label; + double gap() const {return gap_;} //!< Returns the gap caused by adjust(); + void setPosition(Qwt3D::Triple pos, ANCHOR a = BottomLeft); //!< Sets the labels position + void setRelPosition(Tuple rpos, ANCHOR a); //!< Sets the labels position relative to screen + Qwt3D::Triple first() const { return beg_;} //!< Receives bottom left label position + Qwt3D::Triple second() const { return end_;} //!< Receives top right label position + ANCHOR anchor() const { return anchor_; } //!< Defines an anchor point for the labels surrounding rectangle + virtual void setColor(double r, double g, double b, double a = 1); + virtual void setColor(Qwt3D::RGBA rgba); + + /*! + \brief Sets the labels string + For unicode labeling ( QChar(0x3c0) etc.) please look at www.unicode.org. + */ + void setString(QString const& s); + void draw(); //!< Actual drawing + + /** + \brief Decides about use of PDF standard fonts for PDF output + If true, Label can use one of the PDF standard fonts (unprecise positioning for now), + otherwise it dumps pixmaps in the PDF stream (poor quality) + */ + static void useDeviceFonts(bool val); + + +private: + + Qwt3D::Triple beg_, end_, pos_; + QPixmap pm_; + QImage buf_, tex_; + QFont font_; + QString text_; + + ANCHOR anchor_; + + void init(); + void init(const QString & family, int pointSize, int weight = QFont::Normal, bool italic = false); + void update(); //!< Enforces an update of the internal pixmap + void convert2screen(); + double width() const; + double height() const; + + int gap_; + + bool flagforupdate_; + + static bool devicefonts_; + +}; + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_mapping.h b/ChaosDataPlayer/include/qwt3d_mapping.h new file mode 100644 index 0000000..9779468 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_mapping.h @@ -0,0 +1,27 @@ +#ifndef qwt3d_mapping_h__2004_03_05_13_51_begin_guarded_code +#define qwt3d_mapping_h__2004_03_05_13_51_begin_guarded_code + +#include +#include "qwt3d_global.h" +#include "qwt3d_types.h" + +namespace Qwt3D +{ + +//! Abstract base class for general mappings +/** + +*/ +class QWT3D_EXPORT Mapping +{ + +public: + + virtual ~Mapping(){} //!< Destructor. + virtual QString name() const { return QString(""); } //!< Descriptive String. +}; + + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_multiplot.h b/ChaosDataPlayer/include/qwt3d_multiplot.h new file mode 100644 index 0000000..5a1e7cc --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_multiplot.h @@ -0,0 +1,24 @@ +#ifndef qwt3d_multiplot_h__2004_03_06_02_05_begin_guarded_code +#define qwt3d_multiplot_h__2004_03_06_02_05_begin_guarded_code + +#include "qwt3d_plot.h" + +namespace Qwt3D +{ + +//! TODO +class QWT3D_EXPORT MultiPlot : public Plot3D +{ +// Q_OBJECT + +public: + MultiPlot( QWidget* parent = 0, const char* name = 0 ){} + +protected: + virtual void createData() = 0; +}; + +} // ns + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_openglhelper.h b/ChaosDataPlayer/include/qwt3d_openglhelper.h new file mode 100644 index 0000000..5d03721 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_openglhelper.h @@ -0,0 +1,131 @@ +#ifndef __openglhelper_2003_06_06_15_49__ +#define __openglhelper_2003_06_06_15_49__ + +#include "qglobal.h" +#if QT_VERSION < 0x040000 +#include +#else +#include +#include +#endif + +namespace Qwt3D +{ + +#ifndef QWT3D_NOT_FOR_DOXYGEN + +class GLStateBewarer +{ +public: + + GLStateBewarer(GLenum what, bool on, bool persist=false) + { + state_ = what; + stateval_ = glIsEnabled(what); + if (on) + turnOn(persist); + else + turnOff(persist); + } + + ~GLStateBewarer() + { + if (stateval_) + glEnable(state_); + else + glDisable(state_); + } + + void turnOn(bool persist = false) + { + glEnable(state_); + if (persist) + stateval_ = true; + } + + void turnOff(bool persist = false) + { + glDisable(state_); + if (persist) + stateval_ = false; + } + + +private: + + GLenum state_; + bool stateval_; + +}; + +inline const GLubyte* gl_error() +{ + GLenum errcode; + const GLubyte* err = 0; + + if ((errcode = glGetError()) != GL_NO_ERROR) + { + err = gluErrorString(errcode); + } + return err; +} + +inline void SaveGlDeleteLists(GLuint& lstidx, GLsizei range) +{ + if (glIsList(lstidx)) + glDeleteLists(lstidx, range); + lstidx = 0; +} + +//! get OpenGL transformation matrices +/** + Don't rely on (use) this in display lists ! + \param modelMatrix should be a GLdouble[16] + \param projMatrix should be a GLdouble[16] + \param viewport should be a GLint[4] +*/ +inline void getMatrices(GLdouble* modelMatrix, GLdouble* projMatrix, GLint* viewport) +{ + glGetIntegerv(GL_VIEWPORT, viewport); + glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); +} + +//! simplified glut routine (glUnProject): windows coordinates_p --> object coordinates_p +/** + Don't rely on (use) this in display lists ! +*/ +inline bool ViewPort2World(double& objx, double& objy, double& objz, double winx, double winy, double winz) +{ + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + GLint viewport[4]; + + getMatrices(modelMatrix, projMatrix, viewport); + int res = gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, &objx, &objy, &objz); + + return (res == GL_FALSE) ? false : true; +} + +//! simplified glut routine (glProject): object coordinates_p --> windows coordinates_p +/** + Don't rely on (use) this in display lists ! +*/ +inline bool World2ViewPort(double& winx, double& winy, double& winz, double objx, double objy, double objz ) +{ + GLdouble modelMatrix[16]; + GLdouble projMatrix[16]; + GLint viewport[4]; + + getMatrices(modelMatrix, projMatrix, viewport); + int res = gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport, &winx, &winy, &winz); + + return (res == GL_FALSE) ? false : true; +} + + +#endif // QWT3D_NOT_FOR_DOXYGEN + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_parametricsurface.h b/ChaosDataPlayer/include/qwt3d_parametricsurface.h new file mode 100644 index 0000000..7947557 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_parametricsurface.h @@ -0,0 +1,44 @@ +#ifndef qwt3d_parametricsurface_h__2004_03_05_23_43_begin_guarded_code +#define qwt3d_parametricsurface_h__2004_03_05_23_43_begin_guarded_code + +#include "qwt3d_gridmapping.h" + +namespace Qwt3D +{ + +class SurfacePlot; + + +//! Abstract base class for parametric surfaces +/** + +*/ +class QWT3D_EXPORT ParametricSurface : public GridMapping +{ + +public: + ParametricSurface(); //!< Constructs ParametricSurface object w/o assigned SurfacePlot. + //! Constructs ParametricSurface object and assigns a SurfacePlot + explicit ParametricSurface(Qwt3D::SurfacePlot& plotWidget); + //! Constructs ParametricSurface object and assigns a SurfacePlot + explicit ParametricSurface(Qwt3D::SurfacePlot* plotWidget); + //! Overwrite this + virtual Qwt3D::Triple operator()(double u, double v) = 0; + //! Assigns a new SurfacePlot and creates a data representation for it. + virtual bool create(Qwt3D::SurfacePlot& plotWidget); + //! Creates data representation for the actual assigned SurfacePlot. + virtual bool create(); + //! Assigns the object to another widget. To see the changes, you have to call this function before create(). + void assign(Qwt3D::SurfacePlot& plotWidget); + //! Assigns the object to another widget. To see the changes, you have to call this function before create(). + void assign(Qwt3D::SurfacePlot* plotWidget); + //! Provide information about periodicity of the 'u' resp. 'v' domains. + void setPeriodic(bool u, bool v); + +private: + bool uperiodic_, vperiodic_; +}; + +} // ns + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_plot.h b/ChaosDataPlayer/include/qwt3d_plot.h new file mode 100644 index 0000000..ec60d70 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_plot.h @@ -0,0 +1,315 @@ +#ifndef __plot3d_2003_06_09_12_14__ +#define __plot3d_2003_06_09_12_14__ + +#include "qwt3d_coordsys.h" +#include "qwt3d_enrichment_std.h" + +namespace Qwt3D +{ + +//! Base class for all plotting widgets +/*! + Plot3D handles all the common features for plotting widgets - coordinate system, transformations, mouse/keyboard + handling, labeling etc.. It contains some pure virtual functions and is, in so far, an abstract base class. + The class provides interfaces for data handling and implements basic data controlled color allocation. +*/ +class QWT3D_EXPORT Plot3D : public QGLWidget +{ + Q_OBJECT + +public: + +#if QT_VERSION < 0x040000 + Plot3D( QWidget* parent = 0, const char* name = 0 ); +#else + Plot3D ( QWidget * parent = 0, const QGLWidget * shareWidget = 0 ); +#endif + virtual ~Plot3D(); + + QPixmap renderPixmap (int w=0, int h=0, bool useContext=false); + void updateData(); //!< Recalculate data + void createCoordinateSystem(Qwt3D::Triple beg, Qwt3D::Triple end); + Qwt3D::CoordinateSystem* coordinates() { return &coordinates_p; } //!< Returns pointer to CoordinateSystem object + Qwt3D::ColorLegend* legend() { return &legend_;} //!< Returns pointer to ColorLegend object + + double xRotation() const { return xRot_;} //!< Returns rotation around X axis [-360..360] (some angles are equivalent) + double yRotation() const { return yRot_;} //!< Returns rotation around Y axis [-360..360] (some angles are equivalent) + double zRotation() const { return zRot_;} //!< Returns rotation around Z axis [-360..360] (some angles are equivalent) + + double xShift() const { return xShift_;} //!< Returns shift along X axis (object coordinates) + double yShift() const { return yShift_;} //!< Returns shift along Y axis (object coordinates) + double zShift() const { return zShift_;} //!< Returns shift along Z axis (object coordinates) + + double xViewportShift() const { return xVPShift_;} //!< Returns relative shift [-1..1] along X axis (view coordinates) + double yViewportShift() const { return yVPShift_;} //!< Returns relative shift [-1..1] along Y axis (view coordinates) + + double xScale() const { return xScale_;} //!< Returns scaling for X values [0..inf] + double yScale() const { return yScale_;} //!< Returns scaling for Y values [0..inf] + double zScale() const { return zScale_;} //!< Returns scaling for Z values [0..inf] + + double zoom() const { return zoom_;} //!< Returns zoom (0..inf) + + bool ortho() const { return ortho_; } //!< Returns orthogonal (true) or perspective (false) projection + void setPlotStyle( Qwt3D::PLOTSTYLE val); + Qwt3D::Enrichment* setPlotStyle( Qwt3D::Enrichment const& val); + Qwt3D::PLOTSTYLE plotStyle() const { return plotstyle_; }//!< Returns plotting style + //! Returns current Enrichment object used for plotting styles (if set, zero else) + Qwt3D::Enrichment* userStyle() const { return userplotstyle_p; } + void setShading( Qwt3D::SHADINGSTYLE val ); + Qwt3D::SHADINGSTYLE shading() const { return shading_; }//!< Returns shading style + void setIsolines(int isolines); + int isolines() const { return isolines_;} //!< Returns number of isolines + + void setSmoothMesh(bool val) {smoothdatamesh_p = val;} //!< Enables/disables smooth data mesh lines. Default is false + bool smoothDataMesh() const {return smoothdatamesh_p;} //!< True if mesh antialiasing is on + void setBackgroundColor(Qwt3D::RGBA rgba); //!< Sets widgets background color + Qwt3D::RGBA backgroundRGBAColor() const {return bgcolor_;} //!< Returns the widgets background color + void setMeshColor(Qwt3D::RGBA rgba); //!< Sets color for data mesh + Qwt3D::RGBA meshColor() const {return meshcolor_;} //!< Returns color for data mesh + void setMeshLineWidth(double lw); //!< Sets line width for data mesh + double meshLineWidth() const {return meshLineWidth_;} //!< Returns line width for data mesh + void setDataColor(Color* col); //!< Sets new data color object + const Color* dataColor() const {return datacolor_p;} //!< Returns data color object + + virtual Qwt3D::Enrichment* addEnrichment(Qwt3D::Enrichment const&); //!< Add an Enrichment + virtual bool degrade(Qwt3D::Enrichment*); //!< Remove an Enrichment + + Qwt3D::ParallelEpiped hull() const { return hull_;} //!< Returns rectangular hull + + void showColorLegend(bool); + + void setCoordinateStyle(Qwt3D::COORDSTYLE st); //!< Sets style of coordinate system. + void setPolygonOffset(double d); + double polygonOffset() const {return polygonOffset_;} //!< Returns relative value for polygon offset [0..1] + + void setTitlePosition(double rely, double relx = 0.5, Qwt3D::ANCHOR = Qwt3D::TopCenter); + void setTitleFont(const QString& family, int pointSize, int weight = QFont::Normal, bool italic = false); + void setTitleColor(Qwt3D::RGBA col) {title_.setColor(col);} //!< Set caption color + void setTitle(const QString& title) {title_.setString(title);} //!< Set caption text (one row only) + + + void assignMouse(MouseState xrot, MouseState yrot, MouseState zrot, + MouseState xscale, MouseState yscale, MouseState zscale, + MouseState zoom, MouseState xshift, MouseState yshift); + + bool mouseEnabled() const; //!< Returns true, if the widget accept mouse input from the user + void assignKeyboard( + KeyboardState xrot_n, KeyboardState xrot_p + ,KeyboardState yrot_n, KeyboardState yrot_p + ,KeyboardState zrot_n, KeyboardState zrot_p + ,KeyboardState xscale_n, KeyboardState xscale_p + ,KeyboardState yscale_n, KeyboardState yscale_p + ,KeyboardState zscale_n, KeyboardState zscale_p + ,KeyboardState zoom_n, KeyboardState zoom_p + ,KeyboardState xshift_n, KeyboardState xshift_p + ,KeyboardState yshift_n, KeyboardState yshift_p + ); + + bool keyboardEnabled() const; //!< Returns true, if the widget accept keyboard input from the user + //! Sets speed for keyboard driven transformations + void setKeySpeed(double rot, double scale, double shift); + //! Gets speed for keyboard driven transformations + void keySpeed(double& rot, double& scale, double& shift) const; + + bool lightingEnabled() const; //!< Returns true, if Lighting is enabled, false else + //! Turn light on + void illuminate(unsigned light = 0); + //! Turn light off + void blowout(unsigned light = 0); + + void setMaterialComponent(GLenum property, double r, double g, double b, double a = 1.0); + void setMaterialComponent(GLenum property, double intensity); + void setShininess(double exponent); + void setLightComponent(GLenum property, double r, double g, double b, double a = 1.0, unsigned light=0); + void setLightComponent(GLenum property, double intensity, unsigned light=0); + + //! Returns Light 'idx' rotation around X axis [-360..360] (some angles are equivalent) + double xLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.x : 0;} + //! Returns Light 'idx' rotation around Y axis [-360..360] (some angles are equivalent) + double yLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.y : 0;} + //! Returns Light 'idx' rotation around Z axis [-360..360] (some angles are equivalent) + double zLightRotation(unsigned idx = 0) const { return (idx<8) ? lights_[idx].rot.z : 0;} + + //! Returns shift of Light 'idx 'along X axis (object coordinates) + double xLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.x : 0;} + //! Returns shift of Light 'idx 'along Y axis (object coordinates) + double yLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.y : 0;} + //! Returns shift of Light 'idx 'along Z axis (object coordinates) + double zLightShift(unsigned idx = 0) const {return (idx<8) ? lights_[idx].shift.z : 0;} + //! Returns true if valid data available, false else + bool hasData() const { return (actualData_p) ? !actualData_p->empty() : false;} + + +signals: + + //! Emitted, if the rotation is changed + void rotationChanged( double xAngle, double yAngle, double zAngle ); + //! Emitted, if the shift is changed + void shiftChanged( double xShift, double yShift, double zShift ); + //! Emitted, if the viewport shift is changed + void vieportShiftChanged( double xShift, double yShift ); + //! Emitted, if the scaling is changed + void scaleChanged( double xScale, double yScale, double zScale ); + //! Emitted, if the zoom is changed + void zoomChanged(double); + //! Emitted, if the projection mode is changed + void projectionChanged(bool); + +public slots: + + void setRotation( double xVal, double yVal, double zVal ); + void setShift( double xVal, double yVal, double zVal ); + void setViewportShift( double xVal, double yVal ); + void setScale( double xVal, double yVal, double zVal ); + void setZoom( double ); + + void setOrtho(bool); + + void enableMouse(bool val=true); //!< Enable mouse input + void disableMouse(bool val =true); //!< Disable mouse input + void enableKeyboard(bool val=true); //!< Enable keyboard input + void disableKeyboard(bool val =true); //!< Disable keyboard input + + void enableLighting(bool val = true); //!< Turn Lighting on or off + void disableLighting(bool val = true); //!< Turn Lighting on or off + + void setLightRotation( double xVal, double yVal, double zVal, unsigned int idx = 0 ); + void setLightShift( double xVal, double yVal, double zVal, unsigned int idx = 0 ); + + virtual bool savePixmap(QString const& fileName, QString const& format); //!< Saves content to pixmap format + //! Saves content to vector format + virtual bool saveVector(QString const& fileName, QString const& format, VectorWriter::TEXTMODE text, VectorWriter::SORTMODE sortmode); + virtual bool save(QString const& fileName, QString const& format); //!< Saves content + +protected: + typedef std::list EnrichmentList; + typedef EnrichmentList::iterator ELIT; + + void initializeGL(); + void paintGL(); + void resizeGL( int w, int h ); + + void mousePressEvent( QMouseEvent *e ); + void mouseReleaseEvent( QMouseEvent *e ); + void mouseMoveEvent( QMouseEvent *e ); + void wheelEvent( QWheelEvent *e ); + + void keyPressEvent( QKeyEvent *e ); + + Qwt3D::CoordinateSystem coordinates_p; + Qwt3D::Color* datacolor_p; + Qwt3D::Enrichment* userplotstyle_p; + EnrichmentList elist_p; + + virtual void calculateHull() = 0; + virtual void createData() = 0; + virtual void createEnrichment(Qwt3D::Enrichment&){} + virtual void createEnrichments(); + + void createCoordinateSystem(); + void setHull(Qwt3D::ParallelEpiped p) {hull_ = p;} + + bool initializedGL() const {return initializedGL_;} + + enum OBJECTS + { + DataObject, + LegendObject, + NormalObject, + DisplayListSize // only to have a vector length ... + }; + std::vector displaylists_p; + Qwt3D::Data* actualData_p; + + +private: + struct Light + { + Light() : unlit(true){} + bool unlit; + Qwt3D::Triple rot; + Qwt3D::Triple shift; + }; + std::vector lights_; + + GLdouble xRot_, yRot_, zRot_, xShift_, yShift_, zShift_, zoom_ + , xScale_, yScale_, zScale_, xVPShift_, yVPShift_; + + Qwt3D::RGBA meshcolor_; + double meshLineWidth_; + Qwt3D::RGBA bgcolor_; + Qwt3D::PLOTSTYLE plotstyle_; + Qwt3D::SHADINGSTYLE shading_; + Qwt3D::FLOORSTYLE floorstyle_; + bool ortho_; + double polygonOffset_; + int isolines_; + bool displaylegend_; + bool smoothdatamesh_p; + + Qwt3D::ParallelEpiped hull_; + + Qwt3D::ColorLegend legend_; + + Label title_; + Qwt3D::Tuple titlerel_; + Qwt3D::ANCHOR titleanchor_; + + + // mouse + + QPoint lastMouseMovePosition_; + bool mpressed_; + + MouseState xrot_mstate_, + yrot_mstate_, + zrot_mstate_, + xscale_mstate_, + yscale_mstate_, + zscale_mstate_, + zoom_mstate_, + xshift_mstate_, + yshift_mstate_; + + bool mouse_input_enabled_; + + void setRotationMouse(MouseState bstate, double accel, QPoint diff); + void setScaleMouse(MouseState bstate, double accel, QPoint diff); + void setShiftMouse(MouseState bstate, double accel, QPoint diff); + + // keyboard + + bool kpressed_; + + KeyboardState xrot_kstate_[2], + yrot_kstate_[2], + zrot_kstate_[2], + xscale_kstate_[2], + yscale_kstate_[2], + zscale_kstate_[2], + zoom_kstate_[2], + xshift_kstate_[2], + yshift_kstate_[2]; + + bool kbd_input_enabled_; + double kbd_rot_speed_, kbd_scale_speed_, kbd_shift_speed_; + + void setRotationKeyboard(KeyboardState kseq, double speed); + void setScaleKeyboard(KeyboardState kseq, double speed); + void setShiftKeyboard(KeyboardState kseq, double speed); + + + + bool lighting_enabled_; + void applyLight(unsigned idx); + void applyLights(); + + bool initializedGL_; + bool renderpixmaprequest_; +}; + + +} // ns + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_portability.h b/ChaosDataPlayer/include/qwt3d_portability.h new file mode 100644 index 0000000..567a216 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_portability.h @@ -0,0 +1,91 @@ +#ifndef qwt3d_portability_h__2005_07_02_11_55_begin_guarded_code +#define qwt3d_portability_h__2005_07_02_11_55_begin_guarded_code + +//! Portability classes providing transparent Qt3/4 support + +#include +#include "qwt3d_global.h" + +#if QT_VERSION < 0x040000 + +namespace Qwt3D +{ + #define QWT3DLOCAL8BIT(qstring) \ + ((const char*)(qstring.local8Bit())) + + typedef int MouseState; + typedef int KeyboardState; + const Qt::TextFlags SingleLine = Qt::SingleLine; +} // ns + + +#else // Qt4 + +#include + +namespace Qwt3D +{ + + #define QWT3DLOCAL8BIT(qstring) \ + ((const char*)(qstring.toLocal8Bit())) + + const Qt::TextFlag SingleLine = Qt::TextSingleLine; + + //! This class creates a (mouse-button,modifier) pair (ordinary typedef for int if Qt3 is used) + class MouseState + { + public: + MouseState(Qt::MouseButtons mb = Qt::NoButton, Qt::KeyboardModifiers km = Qt::NoModifier) + : mb_(mb), km_(km) + { + } + + MouseState(Qt::MouseButton mb, Qt::KeyboardModifiers km = Qt::NoModifier) + : mb_(mb), km_(km) + { + } + + bool operator==(const MouseState& ms) + { + return mb_ == ms.mb_ && km_ == ms.km_; + } + + bool operator!=(const MouseState& ms) + { + return !operator==(ms); + } + + private: + Qt::MouseButtons mb_; + Qt::KeyboardModifiers km_; + }; + + //! This class creates a (key-button,modifier) pair (ordinary typedef for int if Qt3 is used) + class KeyboardState + { + public: + KeyboardState(int key = Qt::Key_unknown, Qt::KeyboardModifiers km = Qt::NoModifier) + : key_(key), km_(km) + { + } + + bool operator==(const KeyboardState& ms) + { + return key_ == ms.key_ && km_ == ms.km_; + } + + bool operator!=(const KeyboardState& ms) + { + return !operator==(ms); + } + + private: + int key_; + Qt::KeyboardModifiers km_; + }; +} // ns + +#endif + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_scale.h b/ChaosDataPlayer/include/qwt3d_scale.h new file mode 100644 index 0000000..c59c869 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_scale.h @@ -0,0 +1,87 @@ +#ifndef qwt3d_scale_h__2004_06_02_22_02_begin_guarded_code +#define qwt3d_scale_h__2004_06_02_22_02_begin_guarded_code + +#include +#include "qwt3d_types.h" +#include "qwt3d_autoscaler.h" +#include "qwt3d_autoptr.h" + +namespace Qwt3D +{ + +/*! +The class encapsulates non-visual scales. +She is utilized by Axis and also collaborates closely with AutoScaler. +A Scale allows control over all aspects of tic generation including +arbitrary transformations of tic values into corresponding strings. +The strings contain what eventually will be shown as tic labels.\n +Standard linear and logarithmic scales have been integrated yet into the Axis +interface. User-defined axes can be derived from Scale, LinearScale et al. +*/ +class QWT3D_EXPORT Scale +{ + friend class Axis; + friend class qwt3d_ptr; + + protected: + Scale(); + virtual ~Scale(){} + virtual QString ticLabel(unsigned int idx) const; + + virtual void setLimits(double start, double stop); + virtual void setMajors(int val) {majorintervals_p=val;} //!< Sets number of major intervals + virtual void setMinors(int val) {minorintervals_p=val;} //!< Sets number of minor intervals per major interval + virtual void setMajorLimits(double start, double stop); + + int majors() const {return majorintervals_p;} //!< Returns major intervals + int minors() const {return minorintervals_p;} //!< Returns minor intervals + + //! Derived classes should return a new heap based object here. + virtual Scale* clone() const = 0; + //! This function should setup the 2 vectors for major and minor positions; + virtual void calculate() = 0; + virtual int autoscale(double& a, double& b, double start, double stop, int ivals); + + std::vector majors_p, minors_p; + double start_p, stop_p; + int majorintervals_p, minorintervals_p; + double mstart_p, mstop_p; + + private: + void destroy() const {delete this;} //!< Used by qwt3d_ptr +}; + +//! The standard (1:1) mapping class for axis numbering +class QWT3D_EXPORT LinearScale : public Scale +{ + friend class Axis; + friend class qwt3d_ptr; +protected: + int autoscale(double& a, double& b, double start, double stop, int ivals); + //! Returns a new heap based object utilized from qwt3d_ptr + Scale* clone() const {return new LinearScale(*this);} + void calculate(); + LinearAutoScaler autoscaler_p; +}; + +//! log10 scale +class QWT3D_EXPORT LogScale : public Scale +{ + friend class Axis; + friend class qwt3d_ptr; +protected: + QString ticLabel(unsigned int idx) const; + void setMinors(int val); + //! Standard ctor + LogScale(); + //! Returns a new heap based object utilized from qwt3d_ptr + Scale* clone() const {return new LogScale;} + void calculate(); +private: + void setupCounter(double& k, int& step); +}; + +} // namespace Qwt3D + + +#endif /* include guarded */ diff --git a/ChaosDataPlayer/include/qwt3d_surfaceplot.h b/ChaosDataPlayer/include/qwt3d_surfaceplot.h new file mode 100644 index 0000000..7072946 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_surfaceplot.h @@ -0,0 +1,136 @@ +#ifndef qwt3d_SurfacePlot_h__2004_03_05_11_36_begin_guarded_code +#define qwt3d_SurfacePlot_h__2004_03_05_11_36_begin_guarded_code + +#include "qwt3d_plot.h" + +namespace Qwt3D +{ +//! A class representing Surfaces +/** + A SurfacePlot ... + +*/ +class QWT3D_EXPORT SurfacePlot : public Plot3D +{ + Q_OBJECT + +public: +#if QT_VERSION < 0x040000 + SurfacePlot( QWidget* parent = 0, const char* name = 0 ); +#else + SurfacePlot( QWidget * parent = 0, const QGLWidget * shareWidget = 0 ); +#endif + ~SurfacePlot(); + void updateNormals(); //!< Recalculates surface normals; + int resolution() const {return resolution_p;} //!< Returns data resolution (1 means all data) + std::pair facets() const; //!< Returns the number of mesh cells for the ORIGINAL data + bool loadFromData(Qwt3D::Triple** data, unsigned int columns, unsigned int rows + , bool uperiodic = false, bool vperiodic = false); + bool loadFromData(double** data, unsigned int columns, unsigned int rows + ,double minx, double maxx, double miny, double maxy); + bool loadFromData(Qwt3D::TripleField const& data, Qwt3D::CellField const& poly); + + + //! Equivalent to loadFromData(); + /** + \deprecated Use loadFromData instead + */ + bool createDataRepresentation(Qwt3D::Triple** data, unsigned int columns, unsigned int rows + , bool uperiodic = false, bool vperiodic = false) + { + return loadFromData(data, columns, rows, uperiodic, vperiodic); + } + //! Equivalent to loadFromData(); + /** + \deprecated Use loadFromData instead + */ + bool createDataRepresentation(double** data, unsigned int columns, unsigned int rows + ,double minx, double maxx, double miny, double maxy) + { + return loadFromData(data, columns, rows, minx, maxx, miny, maxy); + } + //! Equivalent to loadFromData(); + /** + \deprecated Use loadFromData instead + */ + bool createDataRepresentation(Qwt3D::TripleField const& data, Qwt3D::CellField const& poly) + { + return loadFromData(data, poly); + } + + + Qwt3D::FLOORSTYLE floorStyle() const { return floorstyle_;} //!< Return floor style + void setFloorStyle( Qwt3D::FLOORSTYLE val ) {floorstyle_ = val;} //!< Sets floor style + void showNormals(bool); //!< Draw normals to every vertex + bool normals() const { return datanormals_p;} //!< Returns \c true, if normal drawing is on + + void setNormalLength(double val); //!< Sets length of normals in percent per hull diagonale + double normalLength() const { return normalLength_p; }//!< Returns relative length of normals + void setNormalQuality(int val); //!< Increases plotting quality of normal arrows + int normalQuality() const { return normalQuality_p; }//!< Returns plotting quality of normal arrows + + +signals: + void resolutionChanged(int); + +public slots: + void setResolution( int ); + +protected: + bool datanormals_p; + double normalLength_p; + int normalQuality_p; + + virtual void calculateHull(); + virtual void createData(); + virtual void createEnrichment(Qwt3D::Enrichment& p); + virtual void createFloorData(); + void createNormals(); + void createPoints(); + virtual void createLines(); + + int resolution_p; + + void readIn(Qwt3D::GridData& gdata, Triple** data, unsigned int columns, unsigned int rows); + void readIn(Qwt3D::GridData& gdata, double** data, unsigned int columns, unsigned int rows, + double minx, double maxx, double miny, double maxy); + void calcNormals(GridData& gdata); + void sewPeriodic(GridData& gdata); + + //void calcLowResolution(); +private: + + void Data2Floor(); + void Isolines2Floor(); + + Qwt3D::FLOORSTYLE floorstyle_; + + // grid plot + + Qwt3D::GridData* actualDataG_; + virtual void createDataG(); + virtual void createFloorDataG(); + void createNormalsG(); + void Data2FloorG(); + void Isolines2FloorG(); + void setColorFromVertexG(int ix, int iy, bool skip = false); + + + // mesh plot + + Qwt3D::CellData* actualDataC_; + virtual void createDataC(); + virtual void createFloorDataC(); + void createNormalsC(); + void Data2FloorC(); + void Isolines2FloorC(); + void setColorFromVertexC(int node, bool skip = false); + + + +}; + +} // ns + + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_types.h b/ChaosDataPlayer/include/qwt3d_types.h new file mode 100644 index 0000000..07dcd25 --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_types.h @@ -0,0 +1,457 @@ +#if defined(_MSC_VER) /* MSVC Compiler */ +#pragma warning ( disable : 4786 ) +#endif + +#ifndef __DATATYPES_H__ +#define __DATATYPES_H__ + +#ifdef _DEBUG + #include +#endif + +#include + +#include "qwt3d_global.h" + +#if defined(Q_WS_WIN) + #include +#endif + +#ifndef WHEEL_DELTA + #define WHEEL_DELTA 120 +#endif + +#include "qwt3d_portability.h" +#include "qwt3d_helper.h" +#include "qwt3d_openglhelper.h" + +//! Common namespace for all QwtPlot3D classes +namespace Qwt3D +{ + +const double PI = 3.14159265358979323846264338328; + +//! Plotting style +enum PLOTSTYLE +{ + NOPLOT , //!< No visible data + WIREFRAME , //!< Wireframe style + HIDDENLINE , //!< Hidden Line style + FILLED , //!< Color filled polygons w/o edges + FILLEDMESH , //!< Color filled polygons w/ separately colored edges + POINTS , //!< User defined style (used by Enrichments) + USER , //!< User defined style (used by Enrichments) + LINE3D_STYLE + +}; + +//! Shading style +enum SHADINGSTYLE +{ + FLAT, //!< Flat shading (OpenGL) + GOURAUD //!< Gouraud Shading (OpenGL) +}; + +//! Style of Coordinate system +enum COORDSTYLE +{ + NOCOORD, //!< Coordinate system is not visible + BOX, //!< Boxed + FRAME //!< Frame - 3 visible axes +}; + +//! Different types of axis scales +enum SCALETYPE +{ + LINEARSCALE,//!< Linear scaling + LOG10SCALE, //!< Logarithmic scaling (base 10) + USERSCALE //!< User-defined (for extensions) +}; + +//! Plotting style for floor data (projections) +enum FLOORSTYLE +{ + NOFLOOR, //!< Empty floor + FLOORISO, //!< Isoline projections visible + FLOORDATA //!< Projected polygons visible +}; + +//! Mesh type +enum DATATYPE +{ + GRID, //!< Rectangular grid + POLYGON //!< Convex polygon +}; + +//! The 12 axes +/** +\image html axes.png +*/ +enum AXIS +{ + X1 = 0, //!< 1st x-axis + X2 = 3, //!< 2nd x-axis + X3 = 4, //!< 3th x-axis + X4 = 5, //!< 4th x-axis + Y1 = 1, //!< 1st y-axis + Y2 = 8, //!< 2nd y-axis + Y3 = 7, //!< 3th y-axis + Y4 = 6, //!< 4th y-axis + Z1 = 2, //!< 1st z-axis + Z2 = 9, //!< 2nd z-axis + Z3 = 11, //!< 3th z-axis + Z4 = 10 //!< 4th z-axis +}; + +//! The 6 sides +enum SIDE +{ + NOSIDEGRID = 0, + LEFT = 1 << 0, + RIGHT = 1 << 1, + CEIL = 1 << 2, + FLOOR = 1 << 3, + FRONT = 1 << 4, + BACK = 1 << 5 +}; + +//! Possible anchor points for drawing operations +enum ANCHOR +{ + BottomLeft, + BottomRight, + BottomCenter, + TopLeft, + TopRight, + TopCenter, + CenterLeft, + CenterRight, + Center +}; + + +//! Tuple [x,y] +struct QWT3D_EXPORT Tuple +{ + Tuple() : x(0), y(0) {} //!< Calls Tuple(0,0) + Tuple(double X, double Y) : x(X), y(Y) {} //!< Initialize Tuple with x and y + //! Tuple coordinates + double x,y; +}; + +//! Triple [x,y,z] +/** +Consider Triples also as vectors in R^3 +*/ +struct QWT3D_EXPORT Triple +{ + //! Initialize Triple with x,y and z + explicit Triple(double xv = 0,double yv = 0,double zv = 0) + : x(xv), y(yv), z(zv) + { + } + +#ifndef QWT3D_NOT_FOR_DOXYGEN +#ifdef Q_OS_IRIX + Triple(const Triple& val) + { + if (&val == this) + return; + x = val.x; + y = val.y; + z = val.z; + } + const Triple& operator=(const Triple& val) + { + if (&val == this) + return *this; + x = val.x; + y = val.y; + z = val.z; + return *this; + } +#endif +#endif // QWT3D_NOT_FOR_DOXYGEN + + //! Triple coordinates + double x,y,z; + + Triple& operator+=(Triple t) + { + x += t.x; + y += t.y; + z += t.z; + + return *this; + } + + Triple& operator-=(Triple t) + { + x -= t.x; + y -= t.y; + z -= t.z; + + return *this; + } + Triple& operator*=(double d) + { + x *= d; + y *= d; + z *= d; + + return *this; + } + Triple& operator/=(double d) + { + x /= d; + y /= d; + z /= d; + + return *this; + } + Triple& operator*=(Triple t) // scale + { + x *= t.x; + y *= t.y; + z *= t.z; + + return *this; + } + + bool operator!=(Triple t) const + { + return !isPracticallyZero(x,t.x) || !isPracticallyZero(y,t.y) || !isPracticallyZero(z,t.z); + } + + bool operator==(Triple t) const + { + return !operator!=(t); + } + + double length() const + { + double l2 = x*x + y*y + z*z; + return (isPracticallyZero(l2)) ? 0 :sqrt(l2); + } + + void normalize() + { + double l = length(); + if (l) + *this /= l; + } +}; + +inline const Triple operator+(const Triple& t, const Triple& t2) +{ + return Triple(t) += t2; +} +inline const Triple operator-(const Triple& t, const Triple& t2) +{ + return Triple(t) -= t2; +} +inline const Triple operator*(double d, const Triple& t) +{ + return Triple(t) *= d; +} +inline const Triple operator*(const Triple& t, double d) +{ + return Triple(t) *= d; +} +inline const Triple operator/(double d, const Triple& t) +{ + return Triple(t) /= d; +} +inline const Triple operator/(const Triple& t, double d) +{ + return Triple(t) /= d; +} +inline const Triple operator*(const Triple& t, const Triple& t2) +{ + return Triple(t) *= t2; +} + +//! Parallelepiped spanned by 2 Triples +/** +Please use \em normalized Parallelepipeds:\n\n +minVertex.x <= maxVertex.x\n +minVertex.y <= maxVertex.y\n +minVertex.z <= maxVertex.z\n +*/ +struct QWT3D_EXPORT ParallelEpiped +{ + //! Construct non-initialized Parallelepiped + ParallelEpiped() + { + } + + //! Construct initialized Parallelepiped + /** + minv -> minVertex\n + maxv -> maxVertex\n + */ + ParallelEpiped(Triple minv, Triple maxv) + : minVertex(minv), maxVertex(maxv) + { + } + + Triple minVertex; + Triple maxVertex; +}; + +//! Free vector +/** + FreeVectors represent objects like normal vectors and other vector fields inside R^3 +*/ +struct QWT3D_EXPORT FreeVector +{ + FreeVector() + { + } + + //! Construct initialized vector + /** + b -> base\n + e -> top\n + */ + FreeVector(Triple b, Triple t) + : base(b), top(t) + { + } + + Triple base; + Triple top; +}; + +//! A free vector field in R^3 +typedef std::vector FreeVectorField; + +//! A point field in R^3 +typedef std::vector TripleField; +//! Holds indices in a TripleField interpreted as counterclockwise node numbering for a convex polygon +typedef std::vector Cell; +//! Vector of convex polygons. You need a TripleField as base for the node data +typedef std::vector CellField; +//! Returns the sum over the sizes of the single cells +unsigned tesselationSize(Qwt3D::CellField const& t); + +//! Red-Green-Blue-Alpha value +struct QWT3D_EXPORT RGBA +{ + RGBA() + : r(0), g(0), b(0), a(1) + {} + RGBA(double rr, double gg, double bb, double aa = 1) + : r(rr), g(gg), b(bb), a(aa) + {} + double r,g,b,a; +}; + +//! A Color field +typedef std::vector ColorVector; + +#ifndef QWT3D_NOT_FOR_DOXYGEN + +QWT3D_EXPORT QColor GL2Qt(GLdouble r, GLdouble g, GLdouble b); //!< RGB -> QColor +QWT3D_EXPORT Qwt3D::RGBA Qt2GL(QColor col); //!< QColor -> RGBA + +typedef double *Vertex; +typedef std::vector DataRow; +typedef std::vector DataMatrix; + + +class Data +{ +public: + Qwt3D::DATATYPE datatype; + Data() {datatype= Qwt3D::POLYGON;} + virtual ~Data() {} + virtual void clear() = 0; //!< destroy content + virtual bool empty() const = 0; //!< no data + void setHull(Qwt3D::ParallelEpiped const& h) {hull_p = h;} + Qwt3D::ParallelEpiped const& hull() const {return hull_p;} + +protected: + Qwt3D::ParallelEpiped hull_p; +}; + + +//! Implements a matrix of z-Values with limit access functions +class GridData : public Data +{ +public: + GridData(); + GridData(unsigned int columns, unsigned int rows);//!< see setSize() + ~GridData() { clear();} + + int columns() const; + int rows() const; + + void clear(); //!< destroy content + bool empty() const { return vertices.empty();} + void setSize(unsigned int columns, unsigned int rows); //!< destroys content and set new size, elements are uninitialized + + DataMatrix vertices; //!< mesh vertices + DataMatrix normals; //!< mesh normals + void setPeriodic(bool u, bool v) {uperiodic_ = u; vperiodic_ = v;} + bool uperiodic() const {return uperiodic_;} + bool vperiodic() const {return vperiodic_;} + +private: + bool uperiodic_, vperiodic_; +}; + + +//! Implements a graph-like cell structure with limit access functions +class CellData : public Data +{ +public: + CellData() {datatype=Qwt3D::POLYGON;} + ~CellData() { clear();} + + void clear(); //!< destroy content + bool empty() const { return cells.empty();} + + Triple const& operator()(unsigned cellnumber, unsigned vertexnumber); + + CellField cells; //!< polygon/cell mesh + TripleField nodes; + TripleField normals; //!< mesh normals +}; + +inline Triple normalizedcross(Triple const& u, Triple const& v) +{ + Triple n; + + /* compute the cross product (u x v for right-handed [ccw]) */ + n.x = u.y * v.z - u.z * v.y; + n.y = u.z * v.x - u.x * v.z; + n.z = u.x * v.y - u.y * v.x; + + /* normalize */ + double l = n.length(); + if (l) + { + n /= l; + } + else + { + n = Triple(0,0,0); + } + + return n; +} + +inline double dotProduct(Triple const& u, Triple const& v) +{ + return u.x*v.x + u.y*v.y + u.z*v.z; +} + +void convexhull2d( std::vector& idx, const std::vector& src ); + + +#endif // QWT3D_NOT_FOR_DOXYGEN + +} // ns + +#endif diff --git a/ChaosDataPlayer/include/qwt3d_volumeplot.h b/ChaosDataPlayer/include/qwt3d_volumeplot.h new file mode 100644 index 0000000..45181ea --- /dev/null +++ b/ChaosDataPlayer/include/qwt3d_volumeplot.h @@ -0,0 +1,24 @@ +#ifndef qwt3d_volumeplot_h__2004_03_06_01_52_begin_guarded_code +#define qwt3d_volumeplot_h__2004_03_06_01_52_begin_guarded_code + +#include "qwt3d_plot.h" + +namespace Qwt3D +{ + +//! TODO +class QWT3D_EXPORT VolumePlot : public Plot3D +{ +// Q_OBJECT + +public: + VolumePlot( QWidget* parent = 0, const char* name = 0 ){} + +protected: + virtual void createData() = 0; +}; + +} // ns + + +#endif diff --git a/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.dll b/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.dll new file mode 100644 index 0000000..da659c5 Binary files /dev/null and b/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.dll differ diff --git a/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.prl b/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.prl new file mode 100644 index 0000000..51a31d9 --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/Qt5Qmqtt.prl @@ -0,0 +1,5 @@ +QMAKE_PRL_BUILD_DIR = E:/ThunderDownload/build-qmqtt-Desktop_Qt_5_12_11_MinGW_32_bit-Release/src/mqtt +QMAKE_PRO_INPUT = qmqtt.pro +QMAKE_PRL_TARGET = libQt5Qmqtt.a +QMAKE_PRL_CONFIG = lex yacc depend_includepath testcase_targets import_plugins import_qpa_plugin windows qt_build_extra file_copies qmake_use qt warn_on release link_prl debug_and_release precompile_header shared release no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile optimize_debug precompile_header rdrnd shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl prepare_docs qt_docs_targets no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions warning_clean release ReleaseBuild Release build_pass qtquickcompiler release ReleaseBuild Release build_pass relative_qt_rpath qmake_cache target_qt c++11 strict_c++ c++14 c++1z c99 c11 split_incpath qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext compiler_supports_fpmath create_pc release ReleaseBuild Release build_pass have_target dll exclusive_builds no_autoqmake thread moc resources +QMAKE_PRL_VERSION = 1.0.2 diff --git a/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.dll b/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.dll new file mode 100644 index 0000000..85c302a Binary files /dev/null and b/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.dll differ diff --git a/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.prl b/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.prl new file mode 100644 index 0000000..e494d00 --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/Qt5Qmqttd.prl @@ -0,0 +1,5 @@ +QMAKE_PRL_BUILD_DIR = E:/ThunderDownload/build-qmqtt-Desktop_Qt_5_12_11_MinGW_32_bit-Release/src/mqtt +QMAKE_PRO_INPUT = qmqtt.pro +QMAKE_PRL_TARGET = libQt5Qmqttd.a +QMAKE_PRL_CONFIG = lex yacc debug depend_includepath testcase_targets import_plugins import_qpa_plugin windows qt_build_extra file_copies qmake_use qt warn_on link_prl debug_and_release precompile_header shared no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile optimize_debug precompile_header rdrnd shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl prepare_docs qt_docs_targets no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions warning_clean debug DebugBuild Debug build_pass qtquickcompiler debug DebugBuild Debug build_pass relative_qt_rpath qmake_cache target_qt c++11 strict_c++ c++14 c++1z c99 c11 split_incpath qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext compiler_supports_fpmath create_pc debug DebugBuild Debug build_pass have_target dll no_plist exclusive_builds debug_info no_autoqmake thread moc resources +QMAKE_PRL_VERSION = 1.0.2 diff --git a/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/ExtraSourceIncludes.cmake b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/ExtraSourceIncludes.cmake new file mode 100644 index 0000000..8f1e72c --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/ExtraSourceIncludes.cmake @@ -0,0 +1,7 @@ + +list(APPEND _Qt5Qmqtt_OWN_INCLUDE_DIRS + "E:/ThunderDownload/qmqtt-master/include" "E:/ThunderDownload/qmqtt-master/include/QtQmqtt" +) +set(Qt5Qmqtt_PRIVATE_INCLUDE_DIRS + "E:/ThunderDownload/qmqtt-master/include/QtQmqtt/1.0.2" "E:/ThunderDownload/qmqtt-master/include/QtQmqtt/1.0.2/QtQmqtt" +) diff --git a/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfig.cmake b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfig.cmake new file mode 100644 index 0000000..a1b5dee --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfig.cmake @@ -0,0 +1,185 @@ + +if (CMAKE_VERSION VERSION_LESS 3.1.0) + message(FATAL_ERROR "Qt 5 Qmqtt module requires at least CMake version 3.1.0") +endif() + +get_filename_component(_qt5Qmqtt_install_prefix "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +# For backwards compatibility only. Use Qt5Qmqtt_VERSION instead. +set(Qt5Qmqtt_VERSION_STRING 1.0.2) + +set(Qt5Qmqtt_LIBRARIES Qt5::Qmqtt) + +macro(_qt5_Qmqtt_check_file_exists file) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"Qt5::Qmqtt\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() +endmacro() + +macro(_populate_Qmqtt_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION) + set_property(TARGET Qt5::Qmqtt APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) + + set(imported_location "${_qt5Qmqtt_install_prefix}/bin/${LIB_LOCATION}") + _qt5_Qmqtt_check_file_exists(${imported_location}) + set_target_properties(Qt5::Qmqtt PROPERTIES + "INTERFACE_LINK_LIBRARIES" "${_Qt5Qmqtt_LIB_DEPENDENCIES}" + "IMPORTED_LOCATION_${Configuration}" ${imported_location} + # For backward compatibility with CMake < 2.8.12 + "IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}" "${_Qt5Qmqtt_LIB_DEPENDENCIES}" + ) + + set(imported_implib "${_qt5Qmqtt_install_prefix}/lib/${IMPLIB_LOCATION}") + _qt5_Qmqtt_check_file_exists(${imported_implib}) + if(NOT "${IMPLIB_LOCATION}" STREQUAL "") + set_target_properties(Qt5::Qmqtt PROPERTIES + "IMPORTED_IMPLIB_${Configuration}" ${imported_implib} + ) + endif() +endmacro() + +if (NOT TARGET Qt5::Qmqtt) + + set(_Qt5Qmqtt_OWN_INCLUDE_DIRS "${_qt5Qmqtt_install_prefix}/include/" "${_qt5Qmqtt_install_prefix}/include/QtQmqtt") + set(Qt5Qmqtt_PRIVATE_INCLUDE_DIRS "") + include("${CMAKE_CURRENT_LIST_DIR}/ExtraSourceIncludes.cmake" OPTIONAL) + + foreach(_dir ${_Qt5Qmqtt_OWN_INCLUDE_DIRS}) + _qt5_Qmqtt_check_file_exists(${_dir}) + endforeach() + + # Only check existence of private includes if the Private component is + # specified. + list(FIND Qt5Qmqtt_FIND_COMPONENTS Private _check_private) + if (NOT _check_private STREQUAL -1) + foreach(_dir ${Qt5Qmqtt_PRIVATE_INCLUDE_DIRS}) + _qt5_Qmqtt_check_file_exists(${_dir}) + endforeach() + endif() + + set(Qt5Qmqtt_INCLUDE_DIRS ${_Qt5Qmqtt_OWN_INCLUDE_DIRS}) + + set(Qt5Qmqtt_DEFINITIONS -DQT_QMQTT_LIB) + set(Qt5Qmqtt_COMPILE_DEFINITIONS QT_QMQTT_LIB) + set(_Qt5Qmqtt_MODULE_DEPENDENCIES "Network;Core") + + + set(Qt5Qmqtt_OWN_PRIVATE_INCLUDE_DIRS ${Qt5Qmqtt_PRIVATE_INCLUDE_DIRS}) + + set(_Qt5Qmqtt_FIND_DEPENDENCIES_REQUIRED) + if (Qt5Qmqtt_FIND_REQUIRED) + set(_Qt5Qmqtt_FIND_DEPENDENCIES_REQUIRED REQUIRED) + endif() + set(_Qt5Qmqtt_FIND_DEPENDENCIES_QUIET) + if (Qt5Qmqtt_FIND_QUIETLY) + set(_Qt5Qmqtt_DEPENDENCIES_FIND_QUIET QUIET) + endif() + set(_Qt5Qmqtt_FIND_VERSION_EXACT) + if (Qt5Qmqtt_FIND_VERSION_EXACT) + set(_Qt5Qmqtt_FIND_VERSION_EXACT EXACT) + endif() + + set(Qt5Qmqtt_EXECUTABLE_COMPILE_FLAGS "") + + foreach(_module_dep ${_Qt5Qmqtt_MODULE_DEPENDENCIES}) + if (NOT Qt5${_module_dep}_FOUND) + find_package(Qt5${_module_dep} + 1.0.2 ${_Qt5Qmqtt_FIND_VERSION_EXACT} + ${_Qt5Qmqtt_DEPENDENCIES_FIND_QUIET} + ${_Qt5Qmqtt_FIND_DEPENDENCIES_REQUIRED} + PATHS "${CMAKE_CURRENT_LIST_DIR}/.." NO_DEFAULT_PATH + ) + endif() + + if (NOT Qt5${_module_dep}_FOUND) + set(Qt5Qmqtt_FOUND False) + return() + endif() + + list(APPEND Qt5Qmqtt_INCLUDE_DIRS "${Qt5${_module_dep}_INCLUDE_DIRS}") + list(APPEND Qt5Qmqtt_PRIVATE_INCLUDE_DIRS "${Qt5${_module_dep}_PRIVATE_INCLUDE_DIRS}") + list(APPEND Qt5Qmqtt_DEFINITIONS ${Qt5${_module_dep}_DEFINITIONS}) + list(APPEND Qt5Qmqtt_COMPILE_DEFINITIONS ${Qt5${_module_dep}_COMPILE_DEFINITIONS}) + list(APPEND Qt5Qmqtt_EXECUTABLE_COMPILE_FLAGS ${Qt5${_module_dep}_EXECUTABLE_COMPILE_FLAGS}) + endforeach() + list(REMOVE_DUPLICATES Qt5Qmqtt_INCLUDE_DIRS) + list(REMOVE_DUPLICATES Qt5Qmqtt_PRIVATE_INCLUDE_DIRS) + list(REMOVE_DUPLICATES Qt5Qmqtt_DEFINITIONS) + list(REMOVE_DUPLICATES Qt5Qmqtt_COMPILE_DEFINITIONS) + list(REMOVE_DUPLICATES Qt5Qmqtt_EXECUTABLE_COMPILE_FLAGS) + + set(_Qt5Qmqtt_LIB_DEPENDENCIES "Qt5::Network;Qt5::Core") + + + add_library(Qt5::Qmqtt SHARED IMPORTED) + + set_property(TARGET Qt5::Qmqtt PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${_Qt5Qmqtt_OWN_INCLUDE_DIRS}) + set_property(TARGET Qt5::Qmqtt PROPERTY + INTERFACE_COMPILE_DEFINITIONS QT_QMQTT_LIB) + + set_property(TARGET Qt5::Qmqtt PROPERTY INTERFACE_QT_ENABLED_FEATURES ) + set_property(TARGET Qt5::Qmqtt PROPERTY INTERFACE_QT_DISABLED_FEATURES ) + + set(_Qt5Qmqtt_PRIVATE_DIRS_EXIST TRUE) + foreach (_Qt5Qmqtt_PRIVATE_DIR ${Qt5Qmqtt_OWN_PRIVATE_INCLUDE_DIRS}) + if (NOT EXISTS ${_Qt5Qmqtt_PRIVATE_DIR}) + set(_Qt5Qmqtt_PRIVATE_DIRS_EXIST FALSE) + endif() + endforeach() + + if (_Qt5Qmqtt_PRIVATE_DIRS_EXIST) + add_library(Qt5::QmqttPrivate INTERFACE IMPORTED) + set_property(TARGET Qt5::QmqttPrivate PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${Qt5Qmqtt_OWN_PRIVATE_INCLUDE_DIRS} + ) + set(_Qt5Qmqtt_PRIVATEDEPS) + foreach(dep ${_Qt5Qmqtt_LIB_DEPENDENCIES}) + if (TARGET ${dep}Private) + list(APPEND _Qt5Qmqtt_PRIVATEDEPS ${dep}Private) + endif() + endforeach() + set_property(TARGET Qt5::QmqttPrivate PROPERTY + INTERFACE_LINK_LIBRARIES Qt5::Qmqtt ${_Qt5Qmqtt_PRIVATEDEPS} + ) + endif() + + _populate_Qmqtt_target_properties(RELEASE "Qt5Qmqtt.dll" "libQt5Qmqtt.a" ) + + + + _populate_Qmqtt_target_properties(DEBUG "Qt5Qmqttd.dll" "libQt5Qmqttd.a" ) + + + + file(GLOB pluginTargets "${CMAKE_CURRENT_LIST_DIR}/Qt5Qmqtt_*Plugin.cmake") + + macro(_populate_Qmqtt_plugin_properties Plugin Configuration PLUGIN_LOCATION) + set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) + + set(imported_location "${_qt5Qmqtt_install_prefix}/plugins/${PLUGIN_LOCATION}") + _qt5_Qmqtt_check_file_exists(${imported_location}) + set_target_properties(Qt5::${Plugin} PROPERTIES + "IMPORTED_LOCATION_${Configuration}" ${imported_location} + ) + endmacro() + + if (pluginTargets) + foreach(pluginTarget ${pluginTargets}) + include(${pluginTarget}) + endforeach() + endif() + + + + +_qt5_Qmqtt_check_file_exists("${CMAKE_CURRENT_LIST_DIR}/Qt5QmqttConfigVersion.cmake") + +endif() diff --git a/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfigVersion.cmake b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfigVersion.cmake new file mode 100644 index 0000000..53124b1 --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/cmake/Qt5Qmqtt/Qt5QmqttConfigVersion.cmake @@ -0,0 +1,11 @@ + +set(PACKAGE_VERSION 1.0.2) + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/ChaosDataPlayer/lib/MQTT/libQt5Qmqtt.a b/ChaosDataPlayer/lib/MQTT/libQt5Qmqtt.a new file mode 100644 index 0000000..9f5d247 Binary files /dev/null and b/ChaosDataPlayer/lib/MQTT/libQt5Qmqtt.a differ diff --git a/ChaosDataPlayer/lib/MQTT/libQt5Qmqttd.a b/ChaosDataPlayer/lib/MQTT/libQt5Qmqttd.a new file mode 100644 index 0000000..b8108e5 Binary files /dev/null and b/ChaosDataPlayer/lib/MQTT/libQt5Qmqttd.a differ diff --git a/ChaosDataPlayer/lib/MQTT/pkgconfig/Qt5Qmqtt.pc b/ChaosDataPlayer/lib/MQTT/pkgconfig/Qt5Qmqtt.pc new file mode 100644 index 0000000..62f2ba8 --- /dev/null +++ b/ChaosDataPlayer/lib/MQTT/pkgconfig/Qt5Qmqtt.pc @@ -0,0 +1,13 @@ +prefix=D:/Qt/Qt5.12.11/5.12.11/mingw73_32 +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + + +Name: Qt5 Qmqtt +Description: Qt Qmqtt module +Version: 1.0.2 +Libs: -L${libdir} -lQt5Qmqttd +Cflags: -DQT_QMQTT_LIB -I${includedir}/QtQmqtt -I${includedir} +Requires: Qt5Core Qt5Network + diff --git a/ChaosDataPlayer/lib/QWT3D/libqwtplot3d.a b/ChaosDataPlayer/lib/QWT3D/libqwtplot3d.a new file mode 100644 index 0000000..490f0a0 Binary files /dev/null and b/ChaosDataPlayer/lib/QWT3D/libqwtplot3d.a differ diff --git a/ChaosDataPlayer/lib/QWT3D/qwtplot3d.dll b/ChaosDataPlayer/lib/QWT3D/qwtplot3d.dll new file mode 100644 index 0000000..783fa2d Binary files /dev/null and b/ChaosDataPlayer/lib/QWT3D/qwtplot3d.dll differ diff --git a/ChaosDataPlayer/lib/QWT3D/qwtplot3d.lib b/ChaosDataPlayer/lib/QWT3D/qwtplot3d.lib new file mode 100644 index 0000000..81258c3 Binary files /dev/null and b/ChaosDataPlayer/lib/QWT3D/qwtplot3d.lib differ diff --git a/ChaosDataPlayer/lib/cmake/Qt5qmqtt/ExtraSourceIncludes.cmake b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/ExtraSourceIncludes.cmake new file mode 100644 index 0000000..af61f48 --- /dev/null +++ b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/ExtraSourceIncludes.cmake @@ -0,0 +1,7 @@ + +list(APPEND _Qt5qmqtt_OWN_INCLUDE_DIRS + "E:/qtworkspace/2020.3.16/qmqtt-master/include" "E:/qtworkspace/2020.3.16/qmqtt-master/include/Qtqmqtt" +) +set(Qt5qmqtt_PRIVATE_INCLUDE_DIRS + "E:/qtworkspace/2020.3.16/qmqtt-master/include/Qtqmqtt/1.0.0" "E:/qtworkspace/2020.3.16/qmqtt-master/include/Qtqmqtt/1.0.0/Qtqmqtt" +) diff --git a/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfig.cmake b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfig.cmake new file mode 100644 index 0000000..1795bde --- /dev/null +++ b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfig.cmake @@ -0,0 +1,183 @@ + +if (CMAKE_VERSION VERSION_LESS 2.8.3) + message(FATAL_ERROR "Qt 5 requires at least CMake version 2.8.3") +endif() + +get_filename_component(_qt5qmqtt_install_prefix "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE) + +# For backwards compatibility only. Use Qt5qmqtt_VERSION instead. +set(Qt5qmqtt_VERSION_STRING 1.0.0) + +set(Qt5qmqtt_LIBRARIES Qt5::qmqtt) + +macro(_qt5_qmqtt_check_file_exists file) + if(NOT EXISTS "${file}" ) + message(FATAL_ERROR "The imported target \"Qt5::qmqtt\" references the file + \"${file}\" +but this file does not exist. Possible reasons include: +* The file was deleted, renamed, or moved to another location. +* An install or uninstall procedure did not complete successfully. +* The installation package was faulty and contained + \"${CMAKE_CURRENT_LIST_FILE}\" +but not all the files it references. +") + endif() +endmacro() + +macro(_populate_qmqtt_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION) + set_property(TARGET Qt5::qmqtt APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) + + set(imported_location "${_qt5qmqtt_install_prefix}/bin/${LIB_LOCATION}") + _qt5_qmqtt_check_file_exists(${imported_location}) + set_target_properties(Qt5::qmqtt PROPERTIES + "INTERFACE_LINK_LIBRARIES" "${_Qt5qmqtt_LIB_DEPENDENCIES}" + "IMPORTED_LOCATION_${Configuration}" ${imported_location} + # For backward compatibility with CMake < 2.8.12 + "IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}" "${_Qt5qmqtt_LIB_DEPENDENCIES}" + ) + + set(imported_implib "${_qt5qmqtt_install_prefix}/lib/${IMPLIB_LOCATION}") + _qt5_qmqtt_check_file_exists(${imported_implib}) + if(NOT "${IMPLIB_LOCATION}" STREQUAL "") + set_target_properties(Qt5::qmqtt PROPERTIES + "IMPORTED_IMPLIB_${Configuration}" ${imported_implib} + ) + endif() +endmacro() + +if (NOT TARGET Qt5::qmqtt) + + set(_Qt5qmqtt_OWN_INCLUDE_DIRS "${_qt5qmqtt_install_prefix}/include/" "${_qt5qmqtt_install_prefix}/include/qmqtt") + set(Qt5qmqtt_PRIVATE_INCLUDE_DIRS "") + include("${CMAKE_CURRENT_LIST_DIR}/ExtraSourceIncludes.cmake" OPTIONAL) + + foreach(_dir ${_Qt5qmqtt_OWN_INCLUDE_DIRS}) + _qt5_qmqtt_check_file_exists(${_dir}) + endforeach() + + # Only check existence of private includes if the Private component is + # specified. + list(FIND Qt5qmqtt_FIND_COMPONENTS Private _check_private) + if (NOT _check_private STREQUAL -1) + foreach(_dir ${Qt5qmqtt_PRIVATE_INCLUDE_DIRS}) + _qt5_qmqtt_check_file_exists(${_dir}) + endforeach() + endif() + + set(Qt5qmqtt_INCLUDE_DIRS ${_Qt5qmqtt_OWN_INCLUDE_DIRS}) + + set(Qt5qmqtt_DEFINITIONS -DQT_MQTT_LIB) + set(Qt5qmqtt_COMPILE_DEFINITIONS QT_MQTT_LIB) + set(_Qt5qmqtt_MODULE_DEPENDENCIES "Network;Core") + + + set(Qt5qmqtt_OWN_PRIVATE_INCLUDE_DIRS ${Qt5qmqtt_PRIVATE_INCLUDE_DIRS}) + + set(_Qt5qmqtt_FIND_DEPENDENCIES_REQUIRED) + if (Qt5qmqtt_FIND_REQUIRED) + set(_Qt5qmqtt_FIND_DEPENDENCIES_REQUIRED REQUIRED) + endif() + set(_Qt5qmqtt_FIND_DEPENDENCIES_QUIET) + if (Qt5qmqtt_FIND_QUIETLY) + set(_Qt5qmqtt_DEPENDENCIES_FIND_QUIET QUIET) + endif() + set(_Qt5qmqtt_FIND_VERSION_EXACT) + if (Qt5qmqtt_FIND_VERSION_EXACT) + set(_Qt5qmqtt_FIND_VERSION_EXACT EXACT) + endif() + + set(Qt5qmqtt_EXECUTABLE_COMPILE_FLAGS "") + + foreach(_module_dep ${_Qt5qmqtt_MODULE_DEPENDENCIES}) + if (NOT Qt5${_module_dep}_FOUND) + find_package(Qt5${_module_dep} + 1.0.0 ${_Qt5qmqtt_FIND_VERSION_EXACT} + ${_Qt5qmqtt_DEPENDENCIES_FIND_QUIET} + ${_Qt5qmqtt_FIND_DEPENDENCIES_REQUIRED} + PATHS "${CMAKE_CURRENT_LIST_DIR}/.." NO_DEFAULT_PATH + ) + endif() + + if (NOT Qt5${_module_dep}_FOUND) + set(Qt5qmqtt_FOUND False) + return() + endif() + + list(APPEND Qt5qmqtt_INCLUDE_DIRS "${Qt5${_module_dep}_INCLUDE_DIRS}") + list(APPEND Qt5qmqtt_PRIVATE_INCLUDE_DIRS "${Qt5${_module_dep}_PRIVATE_INCLUDE_DIRS}") + list(APPEND Qt5qmqtt_DEFINITIONS ${Qt5${_module_dep}_DEFINITIONS}) + list(APPEND Qt5qmqtt_COMPILE_DEFINITIONS ${Qt5${_module_dep}_COMPILE_DEFINITIONS}) + list(APPEND Qt5qmqtt_EXECUTABLE_COMPILE_FLAGS ${Qt5${_module_dep}_EXECUTABLE_COMPILE_FLAGS}) + endforeach() + list(REMOVE_DUPLICATES Qt5qmqtt_INCLUDE_DIRS) + list(REMOVE_DUPLICATES Qt5qmqtt_PRIVATE_INCLUDE_DIRS) + list(REMOVE_DUPLICATES Qt5qmqtt_DEFINITIONS) + list(REMOVE_DUPLICATES Qt5qmqtt_COMPILE_DEFINITIONS) + list(REMOVE_DUPLICATES Qt5qmqtt_EXECUTABLE_COMPILE_FLAGS) + + set(_Qt5qmqtt_LIB_DEPENDENCIES "Qt5::Network;Qt5::Core") + + + add_library(Qt5::qmqtt SHARED IMPORTED) + + set_property(TARGET Qt5::qmqtt PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${_Qt5qmqtt_OWN_INCLUDE_DIRS}) + set_property(TARGET Qt5::qmqtt PROPERTY + INTERFACE_COMPILE_DEFINITIONS QT_MQTT_LIB) + + set(_Qt5qmqtt_PRIVATE_DIRS_EXIST TRUE) + foreach (_Qt5qmqtt_PRIVATE_DIR ${Qt5qmqtt_OWN_PRIVATE_INCLUDE_DIRS}) + if (NOT EXISTS ${_Qt5qmqtt_PRIVATE_DIR}) + set(_Qt5qmqtt_PRIVATE_DIRS_EXIST FALSE) + endif() + endforeach() + + if (_Qt5qmqtt_PRIVATE_DIRS_EXIST + AND NOT CMAKE_VERSION VERSION_LESS 3.0.0 ) + add_library(Qt5::qmqttPrivate INTERFACE IMPORTED) + set_property(TARGET Qt5::qmqttPrivate PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${Qt5qmqtt_OWN_PRIVATE_INCLUDE_DIRS} + ) + set(_Qt5qmqtt_PRIVATEDEPS) + foreach(dep ${_Qt5qmqtt_LIB_DEPENDENCIES}) + if (TARGET ${dep}Private) + list(APPEND _Qt5qmqtt_PRIVATEDEPS ${dep}Private) + endif() + endforeach() + set_property(TARGET Qt5::qmqttPrivate PROPERTY + INTERFACE_LINK_LIBRARIES Qt5::qmqtt ${_Qt5qmqtt_PRIVATEDEPS} + ) + endif() + + _populate_qmqtt_target_properties(RELEASE "Qt5qmqtt.dll" "libQt5qmqtt.a" ) + + + + _populate_qmqtt_target_properties(DEBUG "Qt5qmqttd.dll" "libQt5qmqttd.a" ) + + + + file(GLOB pluginTargets "${CMAKE_CURRENT_LIST_DIR}/Qt5qmqtt_*Plugin.cmake") + + macro(_populate_qmqtt_plugin_properties Plugin Configuration PLUGIN_LOCATION) + set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) + + set(imported_location "${_qt5qmqtt_install_prefix}/plugins/${PLUGIN_LOCATION}") + _qt5_qmqtt_check_file_exists(${imported_location}) + set_target_properties(Qt5::${Plugin} PROPERTIES + "IMPORTED_LOCATION_${Configuration}" ${imported_location} + ) + endmacro() + + if (pluginTargets) + foreach(pluginTarget ${pluginTargets}) + include(${pluginTarget}) + endforeach() + endif() + + + + +_qt5_qmqtt_check_file_exists("${CMAKE_CURRENT_LIST_DIR}/Qt5qmqttConfigVersion.cmake") + +endif() diff --git a/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfigVersion.cmake b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfigVersion.cmake new file mode 100644 index 0000000..92241f4 --- /dev/null +++ b/ChaosDataPlayer/lib/cmake/Qt5qmqtt/Qt5qmqttConfigVersion.cmake @@ -0,0 +1,11 @@ + +set(PACKAGE_VERSION 1.0.0) + +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/ChaosDataPlayer/lib/libfftw3-3.dll b/ChaosDataPlayer/lib/libfftw3-3.dll new file mode 100644 index 0000000..f5a97b4 Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3-3.dll differ diff --git a/ChaosDataPlayer/lib/libfftw3-3.lib b/ChaosDataPlayer/lib/libfftw3-3.lib new file mode 100644 index 0000000..c6d07e4 Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3-3.lib differ diff --git a/ChaosDataPlayer/lib/libfftw3f-3.dll b/ChaosDataPlayer/lib/libfftw3f-3.dll new file mode 100644 index 0000000..b0a053a Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3f-3.dll differ diff --git a/ChaosDataPlayer/lib/libfftw3f-3.lib b/ChaosDataPlayer/lib/libfftw3f-3.lib new file mode 100644 index 0000000..ce839b0 Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3f-3.lib differ diff --git a/ChaosDataPlayer/lib/libfftw3l-3.dll b/ChaosDataPlayer/lib/libfftw3l-3.dll new file mode 100644 index 0000000..abc81ea Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3l-3.dll differ diff --git a/ChaosDataPlayer/lib/libfftw3l-3.lib b/ChaosDataPlayer/lib/libfftw3l-3.lib new file mode 100644 index 0000000..1a9c8e8 Binary files /dev/null and b/ChaosDataPlayer/lib/libfftw3l-3.lib differ diff --git a/ChaosDataPlayer/lib/libfreeglut.a b/ChaosDataPlayer/lib/libfreeglut.a new file mode 100644 index 0000000..9876670 Binary files /dev/null and b/ChaosDataPlayer/lib/libfreeglut.a differ diff --git a/ChaosDataPlayer/lib/libfreeglut.lib b/ChaosDataPlayer/lib/libfreeglut.lib new file mode 100644 index 0000000..498a576 Binary files /dev/null and b/ChaosDataPlayer/lib/libfreeglut.lib differ diff --git a/ChaosDataPlayer/lib/libfreeglut_static.a b/ChaosDataPlayer/lib/libfreeglut_static.a new file mode 100644 index 0000000..c502ac5 Binary files /dev/null and b/ChaosDataPlayer/lib/libfreeglut_static.a differ diff --git a/ChaosDataPlayer/lib/libportaudio.a b/ChaosDataPlayer/lib/libportaudio.a new file mode 100644 index 0000000..deb4c64 Binary files /dev/null and b/ChaosDataPlayer/lib/libportaudio.a differ diff --git a/ChaosDataPlayer/lib/libportaudio.dll b/ChaosDataPlayer/lib/libportaudio.dll new file mode 100644 index 0000000..75d53c8 Binary files /dev/null and b/ChaosDataPlayer/lib/libportaudio.dll differ diff --git a/ChaosDataPlayer/lib/libqmqtt.a b/ChaosDataPlayer/lib/libqmqtt.a new file mode 100644 index 0000000..1a8374b Binary files /dev/null and b/ChaosDataPlayer/lib/libqmqtt.a differ diff --git a/ChaosDataPlayer/lib/libqmqttd.a b/ChaosDataPlayer/lib/libqmqttd.a new file mode 100644 index 0000000..77eb1b8 Binary files /dev/null and b/ChaosDataPlayer/lib/libqmqttd.a differ diff --git a/ChaosDataPlayer/lib/libqwtplot3d.a b/ChaosDataPlayer/lib/libqwtplot3d.a new file mode 100644 index 0000000..490f0a0 Binary files /dev/null and b/ChaosDataPlayer/lib/libqwtplot3d.a differ diff --git a/ChaosDataPlayer/lib/pkgconfig/qmqtt.pc b/ChaosDataPlayer/lib/pkgconfig/qmqtt.pc new file mode 100644 index 0000000..34eaa1f --- /dev/null +++ b/ChaosDataPlayer/lib/pkgconfig/qmqtt.pc @@ -0,0 +1,13 @@ +prefix=E:/qtstore/5.10.1/mingw53_32 +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + + +Name: qmqtt +Description: qmqtt module +Version: 1.0.0 +Libs: -L${libdir} -lqmqttd +Cflags: -DQT_MQTT_LIB -I${includedir}/qmqtt -I${includedir} +Requires: Qt5Core Qt5Network + diff --git a/ChaosDataPlayer/lib/qmqtt.dll b/ChaosDataPlayer/lib/qmqtt.dll new file mode 100644 index 0000000..73079bd Binary files /dev/null and b/ChaosDataPlayer/lib/qmqtt.dll differ diff --git a/ChaosDataPlayer/lib/qmqtt.prl b/ChaosDataPlayer/lib/qmqtt.prl new file mode 100644 index 0000000..0b9bd36 --- /dev/null +++ b/ChaosDataPlayer/lib/qmqtt.prl @@ -0,0 +1,5 @@ +QMAKE_PRL_BUILD_DIR = E:/qtworkspace/2020.3.16/build-qmqtt-Desktop_Qt_5_10_1_MinGW_32bit-Release/src/mqtt +QMAKE_PRO_INPUT = mqtt.pro +QMAKE_PRL_TARGET = libqmqtt.a +QMAKE_PRL_CONFIG = lex yacc depend_includepath testcase_targets import_plugins import_qpa_plugin windows qt_build_extra file_copies qmake_use qt warn_on release link_prl debug_and_release precompile_header shared release no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile optimize_debug precompile_header rdrnd shani prefix_build force_independent utf8_source create_prl link_prl prepare_docs qt_docs_targets no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions warning_clean release ReleaseBuild Release build_pass relative_qt_rpath qmake_cache target_qt c++11 strict_c++ c++14 c++1z split_incpath qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext compiler_supports_fpmath create_pc release ReleaseBuild Release build_pass have_target dll exclusive_builds no_autoqmake thread moc resources +QMAKE_PRL_VERSION = 1.0.0 diff --git a/ChaosDataPlayer/lib/qmqttd.dll b/ChaosDataPlayer/lib/qmqttd.dll new file mode 100644 index 0000000..a9449e3 Binary files /dev/null and b/ChaosDataPlayer/lib/qmqttd.dll differ diff --git a/ChaosDataPlayer/lib/qmqttd.prl b/ChaosDataPlayer/lib/qmqttd.prl new file mode 100644 index 0000000..061575c --- /dev/null +++ b/ChaosDataPlayer/lib/qmqttd.prl @@ -0,0 +1,5 @@ +QMAKE_PRL_BUILD_DIR = E:/qtworkspace/2020.3.16/build-qmqtt-Desktop_Qt_5_10_1_MinGW_32bit-Release/src/mqtt +QMAKE_PRO_INPUT = mqtt.pro +QMAKE_PRL_TARGET = libqmqttd.a +QMAKE_PRL_CONFIG = lex yacc debug depend_includepath testcase_targets import_plugins import_qpa_plugin windows qt_build_extra file_copies qmake_use qt warn_on link_prl debug_and_release precompile_header shared no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c largefile optimize_debug precompile_header rdrnd shani prefix_build force_independent utf8_source create_prl link_prl prepare_docs qt_docs_targets no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions warning_clean debug DebugBuild Debug build_pass relative_qt_rpath qmake_cache target_qt c++11 strict_c++ c++14 c++1z split_incpath qt_install_headers need_fwd_pri qt_install_module debug_and_release build_all create_cmake skip_target_version_ext compiler_supports_fpmath create_pc debug DebugBuild Debug build_pass have_target dll no_plist exclusive_builds debug_info no_autoqmake thread moc resources +QMAKE_PRL_VERSION = 1.0.0 diff --git a/ChaosDataPlayer/lib/qwtplot3d.dll b/ChaosDataPlayer/lib/qwtplot3d.dll new file mode 100644 index 0000000..783fa2d Binary files /dev/null and b/ChaosDataPlayer/lib/qwtplot3d.dll differ diff --git a/ChaosDataPlayer/lib/qwtplot3d.lib b/ChaosDataPlayer/lib/qwtplot3d.lib new file mode 100644 index 0000000..81258c3 Binary files /dev/null and b/ChaosDataPlayer/lib/qwtplot3d.lib differ diff --git a/ChaosDataPlayer/line3d.cpp b/ChaosDataPlayer/line3d.cpp new file mode 100644 index 0000000..4f56e2d --- /dev/null +++ b/ChaosDataPlayer/line3d.cpp @@ -0,0 +1,96 @@ +#include "line3d.h" +using namespace Qwt3D; +Qwt3D::Line3D::Line3D() +{ + rgba.a = 1; + rgba.b = 0.3; + rgba.r = 0.6; + rgba.g = 1; +} +Qwt3D::Line3D::Line3D(double thick,bool smooth) +{ + lineThick = thick; + smooth_ = smooth; + rgba.a = 1; + rgba.b = 0.3; + rgba.r = 0.6; + rgba.g = 1; +} + + +void Qwt3D::Line3D::configure(double thick, bool smooth) +{ + lineThick = thick; + smooth_ = smooth; +} + + +void Qwt3D::Line3D::drawBegin() +{ + setDeviceLineWidth(lineThick); + oldstate_ = glIsEnabled(GL_LINE_SMOOTH); + if (smooth_) + glEnable(GL_LINE_SMOOTH); + else + glDisable(GL_LINE_SMOOTH); + //glPointSize(10); + glBegin( GL_LINE_STRIP); + +} + + +void Qwt3D::Line3D::drawEnd() +{ + glEnd(); + + + if (oldstate_) + glEnable(GL_LINE_SMOOTH); + else + glDisable(GL_LINE_SMOOTH); +} + + +void Qwt3D::Line3D::draw(Qwt3D::Triple const& pos) +{ + + + glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); + + + glVertex3d(pos.x,pos.y,pos.z); + +} + + +void Qwt3D::Line3D::draw() +{ + for (int i = 0; i < lineData.size(); i ++) + { + draw(lineData[i]); + } +} + +void Qwt3D::Line3D::rdraw() +{ + for (int i = lineData.size()-1; i >0; i--) + { + draw(lineData[i]); + } +} + + +void Qwt3D::Line3D::add(Qwt3D::Triple const & t) +{ + lineData.push_back(t); +} + + +void Qwt3D::Line3D::setLineColor(RGBA color) +{ + this->rgba = color; +} +//void Qwt3D::Line3D::getColor(int pointIndex) +//{ + +//} diff --git a/ChaosDataPlayer/line3d.h b/ChaosDataPlayer/line3d.h new file mode 100644 index 0000000..df8bcfc --- /dev/null +++ b/ChaosDataPlayer/line3d.h @@ -0,0 +1,49 @@ +#ifndef LINE3D_H +#define LINE3D_H + +#include +#include +#include + +using namespace Qwt3D; + +class QWT3D_EXPORT Line3D: public VertexEnrichment +{ +public: +Line3D(); +Line3D(double thick,bool smooth); +Qwt3D::Enrichment * clone() const{ return new Line3D(*this);} + + +void configure(double thick, bool smooth); +void drawBegin(); +void drawEnd(); +virtual void draw(Qwt3D::Triple const&); + + +virtual void draw(); + + +virtual void add(Qwt3D::Triple const & t); +virtual void setLineColor(RGBA color); + +//mine +virtual void rdraw(); + + +private: +bool smooth_; +double lineThick; +GLboolean oldstate_; + + +std::vector lineData; + + +RGBA rgba; + + +}; + + +#endif // LINE3D_H diff --git a/ChaosDataPlayer/main.cpp b/ChaosDataPlayer/main.cpp new file mode 100644 index 0000000..7064335 --- /dev/null +++ b/ChaosDataPlayer/main.cpp @@ -0,0 +1,55 @@ +#include "MainWidget.h" +#include +#include +#include "LoadingDialog.h" + +using namespace QtCharts; + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWidget windows; + // 显示gif图片 + /*QLabel label; + + // 设置无边框 + label.setWindowFlag(Qt::FramelessWindowHint); + + // 设置透明度 + label.setWindowOpacity(1); + //label.setAttribute(Qt::WA_TranslucentBackground, true); + QMovie movie(":/images/images/loading.gif"); + label.setMovie(&movie); + //label.setText("V1.0"); + QTime time; + time.start(); + movie.start(); + label.show(); + + // 居中显示 + int h = (QApplication::desktop()->height()-label.height())/2; + int w = (QApplication::desktop()->width()-label.width())/2; + label.move(w,h); + // 设置延迟时间 + while (time.elapsed() < 2300) { + QApplication::processEvents(); + } + // 停止 + movie.stop(); + label.close();*/ + QTime time; + time.start(); + LoadingDialog *load = new LoadingDialog; + load->show(); + // 设置延迟时间 + while (time.elapsed() < 3000) { + QApplication::processEvents(); + } + // 停止 + load->close(); + + a.setWindowIcon(QIcon(":/images/images/imgSystem/ICON.ico")); + + windows.show(); + return a.exec(); +} diff --git a/ChaosDataPlayer/mainui.css b/ChaosDataPlayer/mainui.css new file mode 100644 index 0000000..0a159b6 --- /dev/null +++ b/ChaosDataPlayer/mainui.css @@ -0,0 +1,116 @@ +QWidget {color: white; font-family: ΢ź; font-size: 14px; outline:0px} +#m_pMainWgt {border-image:url(:/images/images/bg_main.png);} +#m_pTopWgt {border-image:url(:/images/images/bg_top.png);} +#m_pMinBtn{border-image:url(:/images/images/min_n.png) 5; border-width:5;} +#m_pMinBtn:hover{border-image:url(:/images/images/min_h.png) 5; border-width:5;} +#m_pMinBtn:pressed{border-image:url(:/images/images/min_s.png) 5; border-width:5;} +#m_pMaxBtn{border-image:url(:/images/images/max_n.png) 5; border-width:5;} +#m_pMaxBtn:hover{border-image:url(:/images/images/max_h.png) 5; border-width:5;} +#m_pMaxBtn:pressed{border-image:url(:/images/images/max_s.png) 5; border-width:5;} +#m_pCloseBtn {border: none; background: transparent; border-image: url(:/images/images/close_n.png) 5; border-width: 5;} +#m_pCloseBtn:hover {border-image: url(:/images/images/close_h.png) 5;} +#m_pCloseBtn:pressed {border-image: url(:/images/images/close_s.png) 5;} +#m_pTitleLbl{color:white; font-size:12px;} +#m_pIconLabel{border-image:url(:/images/images/imgSystem/systemIcon.png);} + +QGraphicsView +{ + background:transparent; + margin: 0; +} + +QTreeView,QTableView +{ + alternate-background-color: rgba(142, 185, 233, 25); + background-color: rgba(20,26,31,80); + /*gridline-color: rgba(57, 84, 111, 150);*/ + border: 1px solid #5c7688; + color: #aac3cf; + show-decoration-selected: 1; +} +QTreeView::item,QTableView::item +{ + height: 30px; + border-width: 1; +} +QTreeView::item:hover,QTableView::item:hover +{ + border: none; +} +QTreeView::item:selected,QTableView::item:selected +{ + border: none; + color:#ffa405; +} + + QTabWidget::pane + { /* The tab widget frame */ + border-top: none; + background: transparent; + } + + QTabWidget::tab-bar { + left: 1px; /* move to the right by 5px */ + } + + /* Style the tab using the tab sub-control. Note that + it reads QTabBar _not_ QTabWidget */ + QTabBar::tab { + align: left; + color: #beddfc; + background: #1e272e; + border: 1px solid #000000; + /*border-bottom-color: #C2C7CB; same as the pane color */ + width: 130px; + height: 32px; + padding: 4px; + } + + QTabBar::tab:selected{ + align: left; + color: #beddfc; + background: transparent; + border: none; + /*border-bottom-color: #C2C7CB; same as the pane color */ + width: 130px; + height: 32px; + padding: 4px; + } + + QTabBar::tab:hover + { + align: left; + color: #c47a0f; + background: #1e272e; + border: 1px solid #000000; + /*border-bottom-color: #C2C7CB; same as the pane color */ + width: 130px; + height: 32px; + padding: 4px; + } + QTabBar::tab:pressed { + border: none; + } + QTabBar::tab:selected { + border-color: #9B9B9B; + border-bottom-color: #C2C7CB; /* same as pane color */ + } + + QTabBar::tab:!selected { + margin-top: 2px; /* make non-selected tabs look smaller */ + } + +QScrollBar:vertical { + background: gray; + width: 6px; +} +QScrollBar::handle:vertical { + width: 6px; + background: gray; + min-height: 20px; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + width: 3px; + height: 1px; +} diff --git a/ChaosDataPlayer/mqtt/qmqtt.h b/ChaosDataPlayer/mqtt/qmqtt.h new file mode 100644 index 0000000..6e607dd --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt.h @@ -0,0 +1,38 @@ +/* + * qmqtt.h - qmqtt library heaer + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_H +#define QMQTT_H + +#include +#include + +#endif // QMQTT_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_client.h b/ChaosDataPlayer/mqtt/qmqtt_client.h new file mode 100644 index 0000000..7474a64 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_client.h @@ -0,0 +1,286 @@ +/* + * qmqtt_client.h - qmqtt client header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_CLIENT_H +#define QMQTT_CLIENT_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef QT_WEBSOCKETS_LIB +#include +#endif // QT_WEBSOCKETS_LIB + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +#ifndef Q_ENUM_NS +#define Q_ENUM_NS(x) +#endif // Q_ENUM_NS + +namespace QMQTT { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) +Q_MQTT_EXPORT Q_NAMESPACE +#endif + +static const quint8 LIBRARY_VERSION_MAJOR = 0; +static const quint8 LIBRARY_VERSION_MINOR = 3; +static const quint8 LIBRARY_VERSION_REVISION = 1; +//static const char* LIBRARY_VERSION = "0.3.1"; + +enum MQTTVersion +{ + V3_1_0 = 3, + V3_1_1 = 4 +}; +Q_ENUM_NS(MQTTVersion) + +enum ConnectionState +{ + STATE_INIT = 0, + STATE_CONNECTING, + STATE_CONNECTED, + STATE_DISCONNECTED +}; +Q_ENUM_NS(ConnectionState) + +enum ClientError +{ + UnknownError = 0, + SocketConnectionRefusedError, + SocketRemoteHostClosedError, + SocketHostNotFoundError, + SocketAccessError, + SocketResourceError, + SocketTimeoutError, + SocketDatagramTooLargeError, + SocketNetworkError, + SocketAddressInUseError, + SocketAddressNotAvailableError, + SocketUnsupportedSocketOperationError, + SocketUnfinishedSocketOperationError, + SocketProxyAuthenticationRequiredError, + SocketSslHandshakeFailedError, + SocketProxyConnectionRefusedError, + SocketProxyConnectionClosedError, + SocketProxyConnectionTimeoutError, + SocketProxyNotFoundError, + SocketProxyProtocolError, + SocketOperationError, + SocketSslInternalError, + SocketSslInvalidUserDataError, + SocketTemporaryError, + MqttUnacceptableProtocolVersionError=1<<16, + MqttIdentifierRejectedError, + MqttServerUnavailableError, + MqttBadUserNameOrPasswordError, + MqttNotAuthorizedError, + MqttNoPingResponse +}; +Q_ENUM_NS(ClientError) + +class ClientPrivate; +class Message; +class Frame; +class NetworkInterface; + +class Q_MQTT_EXPORT Client : public QObject +{ + Q_OBJECT + Q_PROPERTY(quint16 _port READ port WRITE setPort) + Q_PROPERTY(QHostAddress _host READ host WRITE setHost) + Q_PROPERTY(QString _hostName READ hostName WRITE setHostName) + Q_PROPERTY(QString _clientId READ clientId WRITE setClientId) + Q_PROPERTY(QString _username READ username WRITE setUsername) + Q_PROPERTY(QByteArray _password READ password WRITE setPassword) + Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive) + Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion) + Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect) + Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval) + Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession) + Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic) + Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos) + Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain) + Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage) + Q_PROPERTY(ConnectionState _connectionState READ connectionState) +#ifndef QT_NO_SSL + Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration) +#endif // QT_NO_SSL + +public: + Client(const QHostAddress& host = QHostAddress::LocalHost, + const quint16 port = 1883, + QObject* parent = nullptr); + +#ifndef QT_NO_SSL + Client(const QString& hostName, + const quint16 port, + const QSslConfiguration& config, + const bool ignoreSelfSigned=false, + QObject* parent = nullptr); +#endif // QT_NO_SSL + + // This function is provided for backward compatibility with older versions of QMQTT. + // If the ssl parameter is true, this function will load a private key ('cert.key') and a local + // certificate ('cert.crt') from the current working directory. It will also set PeerVerifyMode + // to None. This may not be the safest way to set up an SSL connection. + Client(const QString& hostName, + const quint16 port, + const bool ssl, + const bool ignoreSelfSigned, + QObject* parent = nullptr); + +#ifdef QT_WEBSOCKETS_LIB + // Create a connection over websockets + Client(const QString& url, + const QString& origin, + QWebSocketProtocol::Version version, + bool ignoreSelfSigned = false, + QObject* parent = nullptr); + +#ifndef QT_NO_SSL + Client(const QString& url, + const QString& origin, + QWebSocketProtocol::Version version, + const QSslConfiguration& config, + const bool ignoreSelfSigned = false, + QObject* parent = nullptr); +#endif // QT_NO_SSL +#endif // QT_WEBSOCKETS_LIB + + // for testing purposes only + Client(NetworkInterface* network, + const QHostAddress& host = QHostAddress::LocalHost, + const quint16 port = 1883, + QObject* parent = nullptr); + + virtual ~Client(); + + QHostAddress host() const; + QString hostName() const; + quint16 port() const; + QString clientId() const; + QString username() const; + QByteArray password() const; + QMQTT::MQTTVersion version() const; + quint16 keepAlive() const; + bool cleanSession() const; + bool autoReconnect() const; + int autoReconnectInterval() const; + ConnectionState connectionState() const; + QString willTopic() const; + quint8 willQos() const; + bool willRetain() const; + QByteArray willMessage() const; + + bool isConnectedToHost() const; +#ifndef QT_NO_SSL + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration& config); +#endif // QT_NO_SSL + +public Q_SLOTS: + void setHost(const QHostAddress& host); + void setHostName(const QString& hostName); + void setPort(const quint16 port); + void setClientId(const QString& clientId); + void setUsername(const QString& username); + void setPassword(const QByteArray& password); + void setVersion(const MQTTVersion version); + void setKeepAlive(const quint16 keepAlive); + void setCleanSession(const bool cleanSession); + void setAutoReconnect(const bool value); + void setAutoReconnectInterval(const int autoReconnectInterval); + void setWillTopic(const QString& willTopic); + void setWillQos(const quint8 willQos); + void setWillRetain(const bool willRetain); + void setWillMessage(const QByteArray& willMessage); + + void connectToHost(); + void disconnectFromHost(); + + void subscribe(const QString& topic, const quint8 qos = 0); + void unsubscribe(const QString& topic); + + quint16 publish(const QMQTT::Message& message); + +#ifndef QT_NO_SSL + void ignoreSslErrors(); + void ignoreSslErrors(const QList& errors); +#endif // QT_NO_SSL + +Q_SIGNALS: + void connected(); + void disconnected(); + void error(const QMQTT::ClientError error); + + void subscribed(const QString& topic, const quint8 qos = 0); + void unsubscribed(const QString& topic); + void published(const QMQTT::Message& message, quint16 msgid = 0); + void received(const QMQTT::Message& message); + void pingresp(); +#ifndef QT_NO_SSL + void sslErrors(const QList& errors); +#endif // QT_NO_SSL + +protected Q_SLOTS: + void onNetworkConnected(); + void onNetworkDisconnected(); + void onNetworkReceived(const QMQTT::Frame& frame); + void onTimerPingReq(); + void onPingTimeout(); + void onNetworkError(QAbstractSocket::SocketError error); +#ifndef QT_NO_SSL + void onSslErrors(const QList& errors); +#endif // QT_NO_SSL + +protected: + QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(Client) + Q_DECLARE_PRIVATE(Client) +}; + +} // namespace QMQTT + +Q_DECLARE_METATYPE(QMQTT::ClientError) + +#endif // QMQTT_CLIENT_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_client_p.h b/ChaosDataPlayer/mqtt/qmqtt_client_p.h new file mode 100644 index 0000000..72358db --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_client_p.h @@ -0,0 +1,183 @@ +/* + * qmqtt_client_p.h - qmqtt client private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_CLIENT_P_H +#define QMQTT_CLIENT_P_H + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef QT_WEBSOCKETS_LIB +#include +#endif // QT_WEBSOCKETS_LIB + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +namespace QMQTT { + +class NetworkInterface; + +class ClientPrivate +{ +public: + ClientPrivate(Client* qq_ptr); + ~ClientPrivate(); + + void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = nullptr); +#ifndef QT_NO_SSL + void init(const QString& hostName, const quint16 port, const QSslConfiguration& config, + const bool ignoreSelfSigned=false); +#endif // QT_NO_SSL + void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned); +#ifdef QT_WEBSOCKETS_LIB +#ifndef QT_NO_SSL + void init(const QString& url, + const QString& origin, + QWebSocketProtocol::Version version, + const QSslConfiguration* sslConfig, + bool ignoreSelfSigned); +#endif // QT_NO_SSL + void init(const QString& url, + const QString& origin, + QWebSocketProtocol::Version version); +#endif // QT_WEBSOCKETS_LIB + void init(NetworkInterface* network); + + QHostAddress _host; + QString _hostName; + quint16 _port; +#ifdef QT_WEBSOCKETS_LIB + QWebSocketProtocol::Version _webSocketVersion; +#endif // QT_WEBSOCKETS_LIB +#ifndef QT_NO_SSL + bool _ignoreSelfSigned; +#endif // QT_NO_SSL + quint16 _gmid; + MQTTVersion _version; + QString _clientId; + QString _username; + QByteArray _password; + bool _cleanSession; + ConnectionState _connectionState; + QScopedPointer _network; + QTimer _timer; + QTimer _pingResponseTimer; + QString _willTopic; + quint8 _willQos; + bool _willRetain; + QByteArray _willMessage; + QHash _midToTopic; + QHash _midToMessage; + + Client* const q_ptr; + + quint16 nextmid(); + void connectToHost(); + void sendConnect(); + void onTimerPingReq(); + void onPingTimeout(); + quint16 sendUnsubscribe(const QString &topic); + quint16 sendSubscribe(const QString &topic, const quint8 qos); + quint16 sendPublish(const Message &message); + void sendPuback(const quint8 type, const quint16 mid); + void sendDisconnect(); + void sendFrame(const Frame &frame); + void disconnectFromHost(); + void stopKeepAlive(); + void onNetworkConnected(); + void onNetworkDisconnected(); + quint16 publish(const Message& message); + void puback(const quint8 type, const quint16 msgid); + void subscribe(const QString& topic, const quint8 qos); + void unsubscribe(const QString& topic); + void onNetworkReceived(const QMQTT::Frame& frame); + void handleConnack(const quint8 ack); + void handlePublish(const Message& message); + void handlePuback(const quint8 type, const quint16 msgid); + void handleSuback(const QString& topic, const quint8 qos); + void handleUnsuback(const QString& topic); + void handlePingresp(); + bool autoReconnect() const; + void setAutoReconnect(const bool autoReconnect); + int autoReconnectInterval() const; + void setAutoReconnectInterval(const int autoReconnectInterval); + bool isConnectedToHost() const; + QMQTT::ConnectionState connectionState() const; + void setCleanSession(const bool cleanSession); + bool cleanSession() const; + void setKeepAlive(const quint16 keepAlive); + quint16 keepAlive() const; + void setPassword(const QByteArray& password); + QByteArray password() const; + void setUsername(const QString& username); + QString username() const; + void setVersion(const MQTTVersion); + MQTTVersion version() const; + void setClientId(const QString& clientId); + QString clientId() const; + void setPort(const quint16 port); + quint16 port() const; + void setHost(const QHostAddress& host); + QHostAddress host() const; + void setHostName(const QString& hostName); + QString hostName() const; + void setWillTopic(const QString& willTopic); + void setWillQos(const quint8 willQos); + void setWillRetain(const bool willRetain); + void setWillMessage(const QByteArray& willMessage); + QString willTopic() const; + quint8 willQos() const; + bool willRetain() const; + QByteArray willMessage() const; + void onNetworkError(QAbstractSocket::SocketError error); +#ifndef QT_NO_SSL + void ignoreSslErrors(); + void ignoreSslErrors(const QList& errors); + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration& config); + void onSslErrors(const QList& errors); +#endif // QT_NO_SSL + + Q_DECLARE_PUBLIC(Client) +}; + +} // namespace QMQTT + +#endif // QMQTT_CLIENT_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_frame.h b/ChaosDataPlayer/mqtt/qmqtt_frame.h new file mode 100644 index 0000000..2b629c3 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_frame.h @@ -0,0 +1,137 @@ +/* + * qmqtt_frame.h - qmqtt frame heaer + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_FRAME_H +#define QMQTT_FRAME_H + +#include + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QDataStream) + +#define PROTOCOL_MAGIC_3_1_0 "MQIsdp" +#define PROTOCOL_MAGIC_3_1_1 "MQTT" + +#define RANDOM_CLIENT_PREFIX "QMQTT-" + +#define CONNECT 0x10 +#define CONNACK 0x20 +#define PUBLISH 0x30 +#define PUBACK 0x40 +#define PUBREC 0x50 +#define PUBREL 0x60 +#define PUBCOMP 0x70 +#define SUBSCRIBE 0x80 +#define SUBACK 0x90 +#define UNSUBSCRIBE 0xA0 +#define UNSUBACK 0xB0 +#define PINGREQ 0xC0 +#define PINGRESP 0xD0 +#define DISCONNECT 0xE0 + +#define LSB(A) quint8(A & 0x00FF) +#define MSB(A) quint8((A & 0xFF00) >> 8) + +/* +|-------------------------------------- +| 7 6 5 4 | 3 | 2 1 | 0 | +| Type | DUP flag | QoS | RETAIN | +|-------------------------------------- +*/ +#define GETTYPE(HDR) (HDR & 0xF0) +#define SETQOS(HDR, Q) (HDR | ((Q) << 1)) +#define GETQOS(HDR) ((HDR & 0x06) >> 1) +#define SETDUP(HDR, D) (HDR | ((D) << 3)) +#define GETDUP(HDR) ((HDR & 0x08) >> 3) +#define SETRETAIN(HDR, R) (HDR | (R)) +#define GETRETAIN(HDR) (HDR & 0x01) + +/* +|---------------------------------------------------------------------------------- +| 7 | 6 | 5 | 4 3 | 2 | 1 | 0 | +| username | password | willretain | willqos | willflag | cleansession | reserved | +|---------------------------------------------------------------------------------- +*/ +#define FLAG_CLEANSESS(F, C) (F | ((C) << 1)) +#define FLAG_WILL(F, W) (F | ((W) << 2)) +#define FLAG_WILLQOS(F, Q) (F | ((Q) << 3)) +#define FLAG_WILLRETAIN(F, R) (F | ((R) << 5)) +#define FLAG_PASSWD(F, P) (F | ((P) << 6)) +#define FLAG_USERNAME(F, U) (F | ((U) << 7)) + +namespace QMQTT { + +class Q_MQTT_EXPORT Frame +{ +public: + explicit Frame(); + explicit Frame(const quint8 header); + explicit Frame(const quint8 header, const QByteArray &data); + virtual ~Frame(); + + Frame(const Frame& other); + Frame& operator=(const Frame& other); + + bool operator==(const Frame& other) const; + inline bool operator!=(const Frame& other) const + { return !operator==(other); } + + quint8 header() const; + QByteArray data() const; + + quint16 readInt(); + quint8 readChar(); + QByteArray readByteArray(); + QString readString(); + + void writeInt(const quint16 i); + void writeChar(const quint8 c); + void writeByteArray(const QByteArray &data); + void writeString(const QString &string); + void writeRawData(const QByteArray &data); + + //TODO: FIXME LATER + void write(QDataStream &stream) const; + bool encodeLength(QByteArray &lenbuf, int length) const; + +private: + quint8 _header; + QByteArray _data; +}; + +} // namespace QMQTT + +Q_DECLARE_METATYPE(QMQTT::Frame) + +#endif // QMQTT_FRAME_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_global.h b/ChaosDataPlayer/mqtt/qmqtt_global.h new file mode 100644 index 0000000..b2f8bc2 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_global.h @@ -0,0 +1,48 @@ +/* + * qmqtt_global.h - qmqtt libray global + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_GLOBAL_H +#define QMQTT_GLOBAL_H + +#include + +#if !defined(QT_STATIC) && !defined(MQTT_PROJECT_INCLUDE_SRC) +# if defined(QT_BUILD_QMQTT_LIB) +# define Q_MQTT_EXPORT Q_DECL_EXPORT +# else +# define Q_MQTT_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_MQTT_EXPORT +#endif + +#endif // QMQTT_GLOBAL_H + diff --git a/ChaosDataPlayer/mqtt/qmqtt_message.h b/ChaosDataPlayer/mqtt/qmqtt_message.h new file mode 100644 index 0000000..047841e --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_message.h @@ -0,0 +1,96 @@ +/* + * qmqtt_message.h - qmqtt message header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_MESSAGE_H +#define QMQTT_MESSAGE_H + +#include + +#include +#include +#include +#include + +namespace QMQTT { + +class MessagePrivate; + +class Q_MQTT_EXPORT Message +{ +public: + Message(); + explicit Message(const quint16 id, const QString &topic, const QByteArray &payload, + const quint8 qos = 0, const bool retain = false, const bool dup = false); + Message(const Message &other); + ~Message(); + + Message &operator=(const Message &other); +#ifdef Q_COMPILER_RVALUE_REFS + inline Message &operator=(Message &&other) Q_DECL_NOTHROW + { swap(other); return *this; } +#endif + + bool operator==(const Message &other) const; + inline bool operator!=(const Message &other) const + { return !operator==(other); } + + inline void swap(Message &other) Q_DECL_NOTHROW + { qSwap(d, other.d); } + + quint16 id() const; + void setId(const quint16 id); + + quint8 qos() const; + void setQos(const quint8 qos); + + bool retain() const; + void setRetain(const bool retain); + + bool dup() const; + void setDup(const bool dup); + + QString topic() const; + void setTopic(const QString &topic); + + QByteArray payload() const; + void setPayload(const QByteArray &payload); + +private: + QSharedDataPointer d; +}; + +} // namespace QMQTT + +Q_DECLARE_SHARED(QMQTT::Message) + +Q_DECLARE_METATYPE(QMQTT::Message) + +#endif // QMQTT_MESSAGE_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_message_p.h b/ChaosDataPlayer/mqtt/qmqtt_message_p.h new file mode 100644 index 0000000..148019c --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_message_p.h @@ -0,0 +1,83 @@ +/* + * qmqtt_message.h - qmqtt message private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_MESSAGE_P_H +#define QMQTT_MESSAGE_P_H + +#include +#include +#include + +namespace QMQTT { + +class MessagePrivate : public QSharedData +{ +public: + inline MessagePrivate() + : QSharedData(), + id(0), + qos(0), + retain(false), + dup(false) + {} + + inline MessagePrivate(const MessagePrivate &other) + : QSharedData(other), + id(other.id), + qos(other.qos), + retain(other.retain), + dup(other.dup), + topic(other.topic), + payload(other.payload) + {} + + inline MessagePrivate(quint16 id, const QString &topic, const QByteArray &payload, + quint8 qos, bool retain, bool dup) + : QSharedData(), + id(id), + qos(qos), + retain(retain), + dup(dup), + topic(topic), + payload(payload) + {} + + quint16 id; + quint8 qos : 2; + quint8 retain: 1; + quint8 dup: 1; + QString topic; + QByteArray payload; +}; + +} // namespace QMQTT + +#endif // QMQTT_MESSAGE_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_network_p.h b/ChaosDataPlayer/mqtt/qmqtt_network_p.h new file mode 100644 index 0000000..6600197 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_network_p.h @@ -0,0 +1,139 @@ +/* + * qmqtt_network_p.h - qmqtt network private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_NETWORK_P_H +#define QMQTT_NETWORK_P_H + +#include + +#include +#include +#include +#include + +#ifdef QT_WEBSOCKETS_LIB +#include +#endif // QT_WEBSOCKETS_LIB + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +namespace QMQTT { + +class SocketInterface; +class TimerInterface; +class Frame; + +class Network : public NetworkInterface +{ + Q_OBJECT + +public: + Network(QObject* parent = nullptr); +#ifndef QT_NO_SSL + Network(const QSslConfiguration& config, QObject* parent = nullptr); +#endif // QT_NO_SSL +#ifdef QT_WEBSOCKETS_LIB +#ifndef QT_NO_SSL + Network(const QString& origin, + QWebSocketProtocol::Version version, + const QSslConfiguration* sslConfig, + QObject* parent = nullptr); +#endif // QT_NO_SSL + Network(const QString& origin, + QWebSocketProtocol::Version version, + QObject* parent = nullptr); +#endif // QT_WEBSOCKETS_LIB + Network(SocketInterface* socketInterface, TimerInterface* timerInterface, + QObject* parent = nullptr); + ~Network(); + + void sendFrame(const Frame &frame); + bool isConnectedToHost() const; + bool autoReconnect() const; + void setAutoReconnect(const bool autoReconnect); + QAbstractSocket::SocketState state() const; + int autoReconnectInterval() const; + void setAutoReconnectInterval(const int autoReconnectInterval); +#ifndef QT_NO_SSL + void ignoreSslErrors(const QList& errors); + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration& config); +#endif // QT_NO_SSL + +public Q_SLOTS: + void connectToHost(const QHostAddress& host, const quint16 port); + void connectToHost(const QString& hostName, const quint16 port); + void disconnectFromHost(); +#ifndef QT_NO_SSL + void ignoreSslErrors(); +#endif // QT_NO_SSL + +protected Q_SLOTS: + void onSocketError(QAbstractSocket::SocketError socketError); + +protected: + void initialize(); + + quint16 _port; + QHostAddress _host; + QString _hostName; + bool _autoReconnect; + int _autoReconnectInterval; + SocketInterface* _socket; + TimerInterface* _autoReconnectTimer; + + enum ReadState { + Header, + Length, + PayLoad + }; + + ReadState _readState; + quint8 _header; + int _length; + int _shift; + QByteArray _data; + +protected Q_SLOTS: + void onSocketReadReady(); + void onDisconnected(); + void connectToHost(); + +private: + Q_DISABLE_COPY(Network) +}; + +} // namespace QMQTT + +#endif // QMQTT_NETWORK_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_networkinterface.h b/ChaosDataPlayer/mqtt/qmqtt_networkinterface.h new file mode 100644 index 0000000..a431d6b --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_networkinterface.h @@ -0,0 +1,92 @@ +/* + * qmqtt_networkinterface.h - qmqtt network interface header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_NETWORK_INTERFACE_H +#define QMQTT_NETWORK_INTERFACE_H + +#include + +#include +#include +#include +#include +#include + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +namespace QMQTT { + +class Frame; + +class Q_MQTT_EXPORT NetworkInterface : public QObject +{ + Q_OBJECT +public: + explicit NetworkInterface(QObject* parent = nullptr) : QObject(parent) {} + virtual ~NetworkInterface() {} + + virtual void sendFrame(const Frame& frame) = 0; + virtual bool isConnectedToHost() const = 0; + virtual bool autoReconnect() const = 0; + virtual void setAutoReconnect(const bool autoReconnect) = 0; + virtual int autoReconnectInterval() const = 0; + virtual void setAutoReconnectInterval(const int autoReconnectInterval) = 0; + virtual QAbstractSocket::SocketState state() const = 0; +#ifndef QT_NO_SSL + virtual void ignoreSslErrors(const QList& errors) = 0; + virtual QSslConfiguration sslConfiguration() const = 0; + virtual void setSslConfiguration(const QSslConfiguration& config) = 0; +#endif // QT_NO_SSL + +public Q_SLOTS: + virtual void connectToHost(const QHostAddress& host, const quint16 port) = 0; + virtual void connectToHost(const QString& hostName, const quint16 port) = 0; + virtual void disconnectFromHost() = 0; +#ifndef QT_NO_SSL + virtual void ignoreSslErrors() = 0; +#endif // QT_NO_SSL + +Q_SIGNALS: + void connected(); + void disconnected(); + void received(const QMQTT::Frame& frame); + void error(QAbstractSocket::SocketError error); +#ifndef QT_NO_SSL + void sslErrors(const QList& errors); +#endif // QT_NO_SSL +}; + +} // namespace QMQTT + +#endif // QMQTT_NETWORK_INTERFACE_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_routedmessage.h b/ChaosDataPlayer/mqtt/qmqtt_routedmessage.h new file mode 100644 index 0000000..b7e0473 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_routedmessage.h @@ -0,0 +1,71 @@ +/* + * qmqtt_router.h - qmqtt router + * + * Copyright (c) 2013 Ery Lee + * Router added by Niklas Wulf + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_ROUTEDMESSAGE_H +#define QMQTT_ROUTEDMESSAGE_H + +#include + +#include +#include +#include + +namespace QMQTT { + +class RouteSubscription; + +class Q_MQTT_EXPORT RoutedMessage +{ +public: + inline RoutedMessage() + {} + inline RoutedMessage(const Message &message) + : _message(message) + {} + + inline const Message &message() const + { return _message; } + inline QHash parameters() const + { return _parameters; } + +private: + friend class RouteSubscription; + + Message _message; + QHash _parameters; +}; + +} // namespace QMQTT + +Q_DECLARE_METATYPE(QMQTT::RoutedMessage) + +#endif // QMQTT_ROUTEDMESSAGE_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_router.h b/ChaosDataPlayer/mqtt/qmqtt_router.h new file mode 100644 index 0000000..35b04d7 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_router.h @@ -0,0 +1,60 @@ +/* + * qmqtt_router.h - qmqtt router + * + * Copyright (c) 2013 Ery Lee + * Router added by Niklas Wulf + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_ROUTER_H +#define QMQTT_ROUTER_H + +#include + +#include + +namespace QMQTT { + +class Client; +class RouteSubscription; + +class Q_MQTT_EXPORT Router : public QObject +{ + Q_OBJECT +public: + explicit Router(Client *parent = nullptr); + + RouteSubscription *subscribe(const QString &route); + Client *client() const; + +private: + Client *_client; +}; + +} // namespace QMQTT + +#endif // QMQTT_ROUTER_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_routesubscription.h b/ChaosDataPlayer/mqtt/qmqtt_routesubscription.h new file mode 100644 index 0000000..f3925ae --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_routesubscription.h @@ -0,0 +1,79 @@ +/* + * qmqtt_router.h - qmqtt router + * + * Copyright (c) 2013 Ery Lee + * Router added by Niklas Wulf + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_ROUTESUBSCRIPTION_H +#define QMQTT_ROUTESUBSCRIPTION_H + +#include + +#include +#include +#include +#include +#include + +namespace QMQTT { + +class Client; +class Message; +class RoutedMessage; +class Router; + +class Q_MQTT_EXPORT RouteSubscription : public QObject +{ + Q_OBJECT +public: + ~RouteSubscription(); + + QString route() const; + +Q_SIGNALS: + void received(const RoutedMessage &message); + +private Q_SLOTS: + void routeMessage(const Message &message); + +private: + friend class Router; + + explicit RouteSubscription(Router *parent = nullptr); + void setRoute(const QString &route); + + QPointer _client; + QString _topic; + QRegularExpression _regularExpression; + QStringList _parameterNames; +}; + +} // namespace QMQTT + +#endif // QMQTT_ROUTESUBSCRIPTION_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_socket_p.h b/ChaosDataPlayer/mqtt/qmqtt_socket_p.h new file mode 100644 index 0000000..cd971af --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_socket_p.h @@ -0,0 +1,69 @@ +/* + * qmqtt_socket_p.h - qmqtt socket private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_SOCKET_P_H +#define QMQTT_SOCKET_P_H + +#include + +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QIODevice) +QT_FORWARD_DECLARE_CLASS(QTcpSocket) + +namespace QMQTT +{ + +class Socket : public SocketInterface +{ + Q_OBJECT +public: + explicit Socket(QObject* parent = nullptr); + virtual ~Socket(); + + virtual QIODevice *ioDevice(); + void connectToHost(const QHostAddress& address, quint16 port); + void connectToHost(const QString& hostName, quint16 port); + void disconnectFromHost(); + QAbstractSocket::SocketState state() const; + QAbstractSocket::SocketError error() const; + +protected: + QScopedPointer _socket; +}; + +} + +#endif // QMQTT_SOCKET_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_socketinterface.h b/ChaosDataPlayer/mqtt/qmqtt_socketinterface.h new file mode 100644 index 0000000..88257ef --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_socketinterface.h @@ -0,0 +1,84 @@ +/* + * qmqtt_socketinterface.h - qmqtt socket interface header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_SOCKET_INTERFACE_H +#define QMQTT_SOCKET_INTERFACE_H + +#include + +#include +#include +#include +#include +#include + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +namespace QMQTT +{ + +class Q_MQTT_EXPORT SocketInterface : public QObject +{ + Q_OBJECT +public: + explicit SocketInterface(QObject* parent = nullptr) : QObject(parent) {} + virtual ~SocketInterface() {} + + virtual QIODevice* ioDevice() = 0; + virtual void connectToHost(const QHostAddress& address, quint16 port) = 0; + virtual void connectToHost(const QString& hostName, quint16 port) = 0; + virtual void disconnectFromHost() = 0; + virtual QAbstractSocket::SocketState state() const = 0; + virtual QAbstractSocket::SocketError error() const = 0; +#ifndef QT_NO_SSL + virtual void ignoreSslErrors(const QList& errors) { Q_UNUSED(errors); } + virtual void ignoreSslErrors() {} + virtual QSslConfiguration sslConfiguration() const { return QSslConfiguration(); } + virtual void setSslConfiguration(const QSslConfiguration& config) { Q_UNUSED(config); } +#endif // QT_NO_SSL + +Q_SIGNALS: + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); +#ifndef QT_NO_SSL + void sslErrors(const QList& errors); +#endif // QT_NO_SSL +}; + +} + +#endif // QMQTT_SOCKET_INTERFACE_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_ssl_socket_p.h b/ChaosDataPlayer/mqtt/qmqtt_ssl_socket_p.h new file mode 100644 index 0000000..45fbc7c --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_ssl_socket_p.h @@ -0,0 +1,79 @@ +/* + * qmqtt_ssl_socket_p.h - qmqtt SSL socket private header + * + * Copyright (c) 2013 Ery Lee + * Copyright (c) 2016 Matthias Dieter Wallnöfer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_SSL_SOCKET_P_H +#define QMQTT_SSL_SOCKET_P_H + +#ifndef QT_NO_SSL + +#include + +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QSslSocket) +QT_FORWARD_DECLARE_CLASS(QSslError) +#include + +namespace QMQTT +{ + +class SslSocket : public SocketInterface +{ + Q_OBJECT +public: + explicit SslSocket(const QSslConfiguration& config, QObject* parent = nullptr); + virtual ~SslSocket(); + + virtual QIODevice *ioDevice(); + void connectToHost(const QHostAddress& address, quint16 port); + void connectToHost(const QString& hostName, quint16 port); + void disconnectFromHost(); + QAbstractSocket::SocketState state() const; + QAbstractSocket::SocketError error() const; + void ignoreSslErrors(const QList& errors); + void ignoreSslErrors(); + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration& config); + +protected: + QScopedPointer _socket; +}; + +} + +#endif // QT_NO_SSL + +#endif // QMQTT_SSL_SOCKET_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_timer_p.h b/ChaosDataPlayer/mqtt/qmqtt_timer_p.h new file mode 100644 index 0000000..699008e --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_timer_p.h @@ -0,0 +1,62 @@ +/* + * qmqtt_timer_p.h - qmqtt timer private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_TIMER_P_H +#define QMQTT_TIMER_P_H + +#include + +#include +#include + +namespace QMQTT { + +class Timer : public TimerInterface +{ + Q_OBJECT +public: + explicit Timer(QObject *parent = nullptr); + virtual ~Timer(); + + bool isSingleShot() const; + void setSingleShot(bool singleShot); + int interval() const; + void setInterval(int msec); + void start(); + void stop(); + +protected: + QTimer _timer; +}; + +} + +#endif // QMQTT_TIMER_P_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_timerinterface.h b/ChaosDataPlayer/mqtt/qmqtt_timerinterface.h new file mode 100644 index 0000000..2d87415 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_timerinterface.h @@ -0,0 +1,62 @@ +/* + * qmqtt_timerinterface.h - qmqtt timer interface header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_TIMER_INTERFACE_H +#define QMQTT_TIMER_INTERFACE_H + +#include + +#include + +namespace QMQTT { + +class Q_MQTT_EXPORT TimerInterface : public QObject +{ + Q_OBJECT +public: + explicit TimerInterface(QObject* parent = nullptr) : QObject(parent) {} + virtual ~TimerInterface() {} + + virtual bool isSingleShot() const = 0; + virtual void setSingleShot(bool singleShot) = 0; + virtual int interval() const = 0; + virtual void setInterval(int msec) = 0; + virtual void start() = 0; + virtual void stop() = 0; + +Q_SIGNALS: + void timeout(); +}; + +} + +#endif // QMQTT_TIMER_INTERFACE_H + diff --git a/ChaosDataPlayer/mqtt/qmqtt_websocket_p.h b/ChaosDataPlayer/mqtt/qmqtt_websocket_p.h new file mode 100644 index 0000000..ca77363 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_websocket_p.h @@ -0,0 +1,102 @@ +/* + * qmqtt_websocket_p.h - qmqtt socket private header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef QMQTT_WEBSOCKET_H +#define QMQTT_WEBSOCKET_H + +#ifdef QT_WEBSOCKETS_LIB + +#include +#include + +#include +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +#ifndef QT_NO_SSL +#include +QT_FORWARD_DECLARE_CLASS(QSslError) +#endif // QT_NO_SSL + +namespace QMQTT +{ + +class WebSocket : public SocketInterface +{ + Q_OBJECT +public: +#ifndef QT_NO_SSL + WebSocket(const QString& origin, + QWebSocketProtocol::Version version, + const QSslConfiguration* sslConfig, + QObject* parent = nullptr); +#endif // QT_NO_SSL + + WebSocket(const QString& origin, + QWebSocketProtocol::Version version, + QObject* parent = nullptr); + + virtual ~WebSocket(); + + QIODevice *ioDevice() + { + return _ioDevice; + } + + void connectToHost(const QHostAddress& address, quint16 port); + void connectToHost(const QString& hostName, quint16 port); + void disconnectFromHost(); + QAbstractSocket::SocketState state() const; + QAbstractSocket::SocketError error() const; +#ifndef QT_NO_SSL + void ignoreSslErrors(const QList& errors); + void ignoreSslErrors(); + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration& config); +#endif // QT_NO_SSL + +private: + void initialize(); + + QWebSocket *_socket; + WebSocketIODevice *_ioDevice; +}; + +} + +#endif // QT_WEBSOCKETS_LIB + +#endif // QMQTT_WEBSOCKET_H diff --git a/ChaosDataPlayer/mqtt/qmqtt_websocketiodevice_p.h b/ChaosDataPlayer/mqtt/qmqtt_websocketiodevice_p.h new file mode 100644 index 0000000..41d35b2 --- /dev/null +++ b/ChaosDataPlayer/mqtt/qmqtt_websocketiodevice_p.h @@ -0,0 +1,74 @@ +/* + * qmqtt_socketinterface.h - qmqtt socket interface header + * + * Copyright (c) 2013 Ery Lee + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of mqttc nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef QMQTT_WEBSOCKETIODEVICE_H +#define QMQTT_WEBSOCKETIODEVICE_H + +#ifdef QT_WEBSOCKETS_LIB + +#include +#include + +QT_FORWARD_DECLARE_CLASS(QWebSocket) +QT_FORWARD_DECLARE_CLASS(QNetworkRequest) + +namespace QMQTT +{ + +class WebSocketIODevice : public QIODevice +{ + Q_OBJECT +public: + explicit WebSocketIODevice(QWebSocket *socket, QObject *parent = nullptr); + + bool connectToHost(const QNetworkRequest &request); + + virtual qint64 bytesAvailable() const; + +protected: + virtual qint64 readData(char *data, qint64 maxSize); + + virtual qint64 writeData(const char *data, qint64 maxSize); + +private Q_SLOTS: + void binaryMessageReceived(const QByteArray &frame); + +private: + QByteArray _buffer; + QWebSocket *_webSocket; +}; + +} + +#endif // QT_WEBSOCKETS_LIB + +#endif // QMQTT_WEBSOCKETIODEVICE_H diff --git a/ChaosDataPlayer/msgbox.cpp b/ChaosDataPlayer/msgbox.cpp new file mode 100644 index 0000000..233eb19 --- /dev/null +++ b/ChaosDataPlayer/msgbox.cpp @@ -0,0 +1,125 @@ +#include "msgbox.h" + +MsgBox::MsgBox(QMessageBox::Icon icon,const QString &title, const QString &text,QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton, QWidget *parent) : + QDialog(parent) +{ + setModal(true); + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); + this->setStyleSheet("*{background:#1f212c;}\ + QMessageBox{background:rgba(0,0,0,1%);border: 1px solid rgb(42,45,61);}\ + QPushButton{background:rgba(21,131,218,80%);color:white;text-align:center;}\ + QPushButton:hover{background:rgba(21,131,218,1);}\ + QLabel{background:rgba(255,255,255,0%);color:rgba(255,255,255,50%);text-align:center;font-size:15px;}"); + + m_Frame = new QLabel(this); + m_Frame->setStyleSheet("QLabel{border: 1px solid rgba(21,131,218,40%)}"); + m_Logo = new QLabel(this); + m_Logo->setStyleSheet("QLabel{image: url(:/images/images/imgSystem/systemIcon.png); background:rgba(0,0,0,0%);}"); + m_Title = new QLabel(this); + m_Title->setText(title); + m_Title->setStyleSheet("QLabel{background:rgba(0,0,0,0%);color:white}"); + m_BtnClose = new QPushButton(this); + m_BtnClose->setStyleSheet("QPushButton {image: url(:/img/sys_close_normal.png); background:rgba(0,0,0,0%);}\ + QPushButton:hover {image: url(:/img/sys_close_active.png);}"); + + m_MsgBox = new QMessageBox(icon,title,text,buttons); + /*m_MsgBox->setStyleSheet("QMessageBox{background:rgba(0,0,0,1%);border: 1px solid rgb(42,45,61);\ + QLabel{color:white;}\ + QPushButton{background:rgba(21,131,218,80%);color:white;text-align:center;}\ + QPushButton:hover{background:rgba(21,131,218,1);}\ + }");*/ + m_MsgBox->setParent(this); + m_MsgBox->show(); + + resize(m_MsgBox->width()+10,m_MsgBox->height()+26); + m_MsgBox->move(1,25); + + connect(m_BtnClose,SIGNAL(clicked(bool)),this,SLOT(close())); + connect(m_MsgBox,SIGNAL(buttonClicked(QAbstractButton*)),this,SLOT(onButtonClicked(QAbstractButton*))); +} + +MsgBox::~MsgBox() +{ + delete m_Title; + delete m_Logo; + delete m_BtnClose; + delete m_MsgBox; + deleteLater(); +} + +void MsgBox::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} + +void MsgBox::resizeEvent(QResizeEvent *Size) +{ + int total_width = Size->size().width(); + int total_height = Size->size().height(); + m_Frame->setGeometry(0,0,total_width,total_height); + int title_h = 25; + m_Logo->setGeometry(0,0,title_h,title_h); + m_Title->setGeometry(title_h,0,total_width-2*title_h,title_h); + m_BtnClose->setGeometry(total_width-title_h,0,title_h,title_h); + //m_MsgBox->setGeometry(0,title_h,total_width,total_height-title_h); +} + +void MsgBox::mouseReleaseEvent(QMouseEvent *event) +{ + //for move windows + if((true==m_MouseLButtonPressed) + &&(event->button() == Qt::LeftButton)) + { + m_MouseLButtonPressed = false; + } +} + +void MsgBox::mousePressEvent(QMouseEvent *event) +{ + //for move windows + if(event->button() == Qt::LeftButton) + { + int y = event->pos().y(); + if((y<30)||(y>this->height()-30)) + { + m_MouseLButtonPressed=true; + m_dPos = event->globalPos() - this->pos(); + } + } +} + +void MsgBox::mouseMoveEvent(QMouseEvent *event) +{ + if(m_MouseLButtonPressed) + { + this->move(event->globalPos() - m_dPos); + } + + QWidget::mouseMoveEvent(event); +} + +void MsgBox::onButtonClicked(QAbstractButton *button) +{ + int nResult = m_MsgBox->standardButton(button); + m_MsgBox->done(nResult); + this->close(); +} + +QMessageBox::StandardButton MsgBox::standardButton(QAbstractButton *button) const +{ + return (QMessageBox::StandardButton)m_MsgBox->standardButton(button); +} + +QMessageBox::StandardButton MyMsgBox(QMessageBox::Icon icon,const QString &title, const QString &text,QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton, QWidget *parent) +{ + MsgBox *msgbox = new MsgBox(icon,title,text,buttons,defaultButton,parent); + msgbox->show(); + + if (msgbox->m_MsgBox->exec() == -1) + return QMessageBox::Cancel; + return msgbox->m_MsgBox->standardButton(msgbox->m_MsgBox->clickedButton()); +} diff --git a/ChaosDataPlayer/msgbox.h b/ChaosDataPlayer/msgbox.h new file mode 100644 index 0000000..30c21eb --- /dev/null +++ b/ChaosDataPlayer/msgbox.h @@ -0,0 +1,57 @@ +#ifndef MSGBOX_H +#define MSGBOX_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#if _MSC_VER >= 1600 +#pragma execution_character_set("utf-8") +#endif + +QMessageBox::StandardButton MyMsgBox(QMessageBox::Icon icon, const QString &title = "Tip", + const QString &text = "Success", QMessageBox::StandardButtons buttons = QMessageBox::Ok, + QMessageBox::StandardButton defaultButton = QMessageBox::Ok,QWidget *parent = 0); + + +class MsgBox : public QDialog +{ + Q_OBJECT + +public: + explicit MsgBox(QMessageBox::Icon icon,const QString &title, const QString &text, + QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton,QWidget *parent = 0); + ~MsgBox(); + + QMessageBox *m_MsgBox; + +protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *Size); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +private: + QLabel *m_Frame; + QLabel *m_Logo; + QLabel *m_Title; + QPushButton *m_BtnClose; + + + + QPoint m_dPos; + bool m_MouseLButtonPressed; + + QMessageBox::StandardButton standardButton(QAbstractButton *button) const; + +private slots: + void onButtonClicked(QAbstractButton *button); +}; + +#endif // MSGBOX_H diff --git a/ChaosDataPlayer/mylineplot3d.cpp b/ChaosDataPlayer/mylineplot3d.cpp new file mode 100644 index 0000000..0289a7d --- /dev/null +++ b/ChaosDataPlayer/mylineplot3d.cpp @@ -0,0 +1,203 @@ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mylineplot3d.h" +#include "line3d.h" + + +using namespace Qwt3D; + +class Rosenbrock:public Function{ +public: + Rosenbrock(SurfacePlot & pw):Function(pw){} + Rosenbrock(){} + double operator ()(double x,double y){ + return x*y/2; + return x*sin(y)* log(x) + y* cos(x); + return log(sin(x) * cos(y)); + return log((1-x)*(1-x) + 100 * (y - x*x)*(y - x*x)) / 8; + } +}; + + +mylineplot3d::mylineplot3d() +{ + myxMax = 80; + myyMax = 60; + myzMax = 60; + + int xscal = myxMax/myzMax; + int yscal = myyMax/myzMax; + + myCurxMax = 0.0; + myCurxMin = 0.0; + myCuryMax = 0.0; + myCuryMin = 0.0; + myCurzMax = 0.0; + myCurzMin = 0.0; + + setPlotStyle(Qwt3D::LINE3D_STYLE); + //setPlotStyle(Qwt3D::NOPLOT); + coordinates()->setAutoScale(); + +// setTitle("A Simple SurfacePlot Demonstration"); + setIsolines(10); + Rosenbrock rosenbrock; +/* coordinates()->setGridLines(true,true,Qwt3D::LEFT|Qwt3D::BACK|Qwt3D::FLOOR); + rosenbrock.setMesh(10,10); + rosenbrock.setDomain(0,myxMax,0,myyMax); + rosenbrock.setMinZ(0); + rosenbrock.setMaxZ(myzMax); + + rosenbrock.create(*this);*/ + setShift(1,0,0); + setRotation(30,0,15); +// setScale(1,1,10); + setCurMaxMin(0,myxMax,0,myyMax,0,myzMax); +// setScale(xscal,yscal,10); + setShift(0.15,0,0); + setZoom(1); + int axesCount = coordinates()->axes.size(); + for (unsigned i=0; i != axesCount; ++i) + { + coordinates()->axes[i].setMajors(6); + coordinates()->axes[i].setMinors(1); + } + + coordinates()->axes[X1].setLabelString("Frequency,Hz"); + coordinates()->axes[Y2].setLabelString("Time,S"); + coordinates()->axes[Z4].setLabelString("m/s2"); + + setCoordinateStyle(BOX); + + updateData(); + updateGL(); + +} +mylineplot3d::~mylineplot3d() +{ + +} + +void mylineplot3d::init() +{ + +} + +void mylineplot3d::createLines() +{ + +} + +void mylineplot3d::keyPressEvent(QKeyEvent * e) +{ + int c = e->key(); + + if(e->key() == Qt::Key_Up) + { + setShift(1,0,0); + setRotation(30,0,15); + setScale(1,1,1); + setShift(0.15,0,0); + setZoom(0.9); + } + else if(c == 65) + { + printf("set scale %f %f %f\n ",xScale(),yScale()*1.2,zScale()); + setScale(1,1,zScale() * 1.2); + } +} + +void mylineplot3d::tick() +{ + updateData(); + updateGL(); +} + +void mylineplot3d::setCurMaxMin(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax) +{ + if (xmin < myCurxMin) + { + myCurxMin = xmin; + } + if (xmax > myCurxMax) + { + myCurxMax = xmax; + } + + if (ymin < myCuryMin) + { + myCuryMin = ymin; + } + + if (ymax > myCuryMax) + { + myCuryMax = ymax; + } + + if (zmin < myCurzMin) + { + myCurzMin = zmin; + } + + if (zmax > myCurzMax) + { + myCurzMax = zmax; + } + + + if ((myCurxMax - myxMax) > 1 ) + { + myxMax += 10; + myyMax = myxMax; + + Rosenbrock rosenbrock; + rosenbrock.setMesh(5,5); + rosenbrock.setDomain(-10,myxMax,-10,myyMax); + rosenbrock.setMinZ(0); + rosenbrock.setMaxZ(myzMax); + rosenbrock.create(*this); + + double _yScale = myxMax / myzMax; + _yScale = (myxMax / myzMax) > _yScale? (myyMax / myzMax): _yScale; + setScale(1,1,_yScale); + + } + + if ((myCuryMax - myyMax) > 1) + { + myyMax += 10; + myxMax = myyMax; + Rosenbrock rosenbrock; + rosenbrock.setMesh(5,5); + rosenbrock.setDomain(-10,myxMax,-10,myyMax); + rosenbrock.setMinZ(0); + rosenbrock.setMaxZ(myzMax); + rosenbrock.create(*this); + + double _yScale = myxMax / myzMax; + _yScale = (myxMax / myzMax) > _yScale? (myyMax / myzMax): _yScale; + setScale(1,1,_yScale); + } + + if (myCurzMax > myzMax) + { + myzMax += 10; + + Rosenbrock rosenbrock; + rosenbrock.setMesh(5,5); + rosenbrock.setDomain(-10,myxMax,-10,myyMax); + rosenbrock.setMinZ(0); + rosenbrock.setMaxZ(myzMax); + rosenbrock.create(*this); + } + updateData(); + updateGL(); +} diff --git a/ChaosDataPlayer/mylineplot3d.h b/ChaosDataPlayer/mylineplot3d.h new file mode 100644 index 0000000..54646cd --- /dev/null +++ b/ChaosDataPlayer/mylineplot3d.h @@ -0,0 +1,38 @@ +#ifndef MYLINEPLOT3D_H +#define MYLINEPLOT3D_H +#include "include/qwt3d_surfaceplot.h" +#include "include/qwt3d_global.h" + +class QWT3D_EXPORT mylineplot3d: public Qwt3D::SurfacePlot +{ + //Q_OBJECT +public: + mylineplot3d(); + ~mylineplot3d(); + + virtual void init(); + + virtual void createLines(); + + virtual void keyPressEvent(QKeyEvent *); + + virtual void tick(); + virtual void setCurMaxMin(double xmin,double xmax,double ymin,double ymax,double zmin,double zmax); +private: + int myTimerId; + + int time_; + + double myxMax; + double myyMax; + double myzMax; + + double myCurxMin; + double myCuryMin; + double myCurzMin; + double myCurxMax; + double myCuryMax; + double myCurzMax; +}; + +#endif // MYLINEPLOT3D_H diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlite.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlite.dll new file mode 100644 index 0000000..c9b1c55 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlite.dll differ diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlited.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlited.dll new file mode 100644 index 0000000..94c93d6 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlited.dll differ diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlodbc.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlodbc.dll new file mode 100644 index 0000000..ccfb753 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlodbc.dll differ diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlodbcd.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlodbcd.dll new file mode 100644 index 0000000..a1e9a38 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlodbcd.dll differ diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlpsql.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlpsql.dll new file mode 100644 index 0000000..0cf39b6 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlpsql.dll differ diff --git a/ChaosDataPlayer/plugins/sqldrivers/qsqlpsqld.dll b/ChaosDataPlayer/plugins/sqldrivers/qsqlpsqld.dll new file mode 100644 index 0000000..9d120f0 Binary files /dev/null and b/ChaosDataPlayer/plugins/sqldrivers/qsqlpsqld.dll differ diff --git a/ChaosDataPlayer/portaudio.h b/ChaosDataPlayer/portaudio.h new file mode 100644 index 0000000..8a8250f --- /dev/null +++ b/ChaosDataPlayer/portaudio.h @@ -0,0 +1,1243 @@ +#ifndef PORTAUDIO_H +#define PORTAUDIO_H +/* + * $Id$ + * PortAudio Portable Real-Time Audio Library + * PortAudio API Header File + * Latest version available at: http://www.portaudio.com/ + * + * Copyright (c) 1999-2002 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief The portable PortAudio API. +*/ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** Retrieve the release number of the currently running PortAudio build. + For example, for version "19.5.1" this will return 0x00130501. + + @see paMakeVersionNumber +*/ +int Pa_GetVersion( void ); + +/** Retrieve a textual description of the current PortAudio build, + e.g. "PortAudio V19.5.0-devel, revision 1952M". + The format of the text may change in the future. Do not try to parse the + returned string. + + @deprecated As of 19.5.0, use Pa_GetVersionInfo()->versionText instead. +*/ +const char* Pa_GetVersionText( void ); + +/** + Generate a packed integer version number in the same format used + by Pa_GetVersion(). Use this to compare a specified version number with + the currently running version. For example: + + @code + if( Pa_GetVersion() < paMakeVersionNumber(19,5,1) ) {} + @endcode + + @see Pa_GetVersion, Pa_GetVersionInfo + @version Available as of 19.5.0. +*/ +#define paMakeVersionNumber(major, minor, subminor) \ + (((major)&0xFF)<<16 | ((minor)&0xFF)<<8 | ((subminor)&0xFF)) + + +/** + A structure containing PortAudio API version information. + @see Pa_GetVersionInfo, paMakeVersionNumber + @version Available as of 19.5.0. +*/ +typedef struct PaVersionInfo { + int versionMajor; + int versionMinor; + int versionSubMinor; + /** + This is currently the Git revision hash but may change in the future. + The versionControlRevision is updated by running a script before compiling the library. + If the update does not occur, this value may refer to an earlier revision. + */ + const char *versionControlRevision; + /** Version as a string, for example "PortAudio V19.5.0-devel, revision 1952M" */ + const char *versionText; +} PaVersionInfo; + +/** Retrieve version information for the currently running PortAudio build. + @return A pointer to an immutable PaVersionInfo structure. + + @note This function can be called at any time. It does not require PortAudio + to be initialized. The structure pointed to is statically allocated. Do not + attempt to free it or modify it. + + @see PaVersionInfo, paMakeVersionNumber + @version Available as of 19.5.0. +*/ +const PaVersionInfo* Pa_GetVersionInfo( void ); + + +/** Error codes returned by PortAudio functions. + Note that with the exception of paNoError, all PaErrorCodes are negative. +*/ + +typedef int PaError; +typedef enum PaErrorCode +{ + paNoError = 0, + + paNotInitialized = -10000, + paUnanticipatedHostError, + paInvalidChannelCount, + paInvalidSampleRate, + paInvalidDevice, + paInvalidFlag, + paSampleFormatNotSupported, + paBadIODeviceCombination, + paInsufficientMemory, + paBufferTooBig, + paBufferTooSmall, + paNullCallback, + paBadStreamPtr, + paTimedOut, + paInternalError, + paDeviceUnavailable, + paIncompatibleHostApiSpecificStreamInfo, + paStreamIsStopped, + paStreamIsNotStopped, + paInputOverflowed, + paOutputUnderflowed, + paHostApiNotFound, + paInvalidHostApi, + paCanNotReadFromACallbackStream, + paCanNotWriteToACallbackStream, + paCanNotReadFromAnOutputOnlyStream, + paCanNotWriteToAnInputOnlyStream, + paIncompatibleStreamHostApi, + paBadBufferPtr +} PaErrorCode; + + +/** Translate the supplied PortAudio error code into a human readable + message. +*/ +const char *Pa_GetErrorText( PaError errorCode ); + + +/** Library initialization function - call this before using PortAudio. + This function initializes internal data structures and prepares underlying + host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(), + and Pa_GetErrorText(), this function MUST be called before using any other + PortAudio API functions. + + If Pa_Initialize() is called multiple times, each successful + call must be matched with a corresponding call to Pa_Terminate(). + Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not + required to be fully nested. + + Note that if Pa_Initialize() returns an error code, Pa_Terminate() should + NOT be called. + + @return paNoError if successful, otherwise an error code indicating the cause + of failure. + + @see Pa_Terminate +*/ +PaError Pa_Initialize( void ); + + +/** Library termination function - call this when finished using PortAudio. + This function deallocates all resources allocated by PortAudio since it was + initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has + been called multiple times, each call must be matched with a corresponding call + to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically + close any PortAudio streams that are still open. + + Pa_Terminate() MUST be called before exiting a program which uses PortAudio. + Failure to do so may result in serious resource leaks, such as audio devices + not being available until the next reboot. + + @return paNoError if successful, otherwise an error code indicating the cause + of failure. + + @see Pa_Initialize +*/ +PaError Pa_Terminate( void ); + + + +/** The type used to refer to audio devices. Values of this type usually + range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice + and paUseHostApiSpecificDeviceSpecification values. + + @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification +*/ +typedef int PaDeviceIndex; + + +/** A special PaDeviceIndex value indicating that no device is available, + or should be used. + + @see PaDeviceIndex +*/ +#define paNoDevice ((PaDeviceIndex)-1) + + +/** A special PaDeviceIndex value indicating that the device(s) to be used + are specified in the host api specific stream info structure. + + @see PaDeviceIndex +*/ +#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) + + +/* Host API enumeration mechanism */ + +/** The type used to enumerate to host APIs at runtime. Values of this type + range from 0 to (Pa_GetHostApiCount()-1). + + @see Pa_GetHostApiCount +*/ +typedef int PaHostApiIndex; + + +/** Retrieve the number of available host APIs. Even if a host API is + available it may have no devices available. + + @return A non-negative value indicating the number of available host APIs + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + @see PaHostApiIndex +*/ +PaHostApiIndex Pa_GetHostApiCount( void ); + + +/** Retrieve the index of the default host API. The default host API will be + the lowest common denominator host API on the current platform and is + unlikely to provide the best performance. + + @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) + indicating the default host API index or, a PaErrorCode (which are always + negative) if PortAudio is not initialized or an error is encountered. +*/ +PaHostApiIndex Pa_GetDefaultHostApi( void ); + + +/** Unchanging unique identifiers for each supported host API. This type + is used in the PaHostApiInfo structure. The values are guaranteed to be + unique and to never change, thus allowing code to be written that + conditionally uses host API specific extensions. + + New type ids will be allocated when support for a host API reaches + "public alpha" status, prior to that developers should use the + paInDevelopment type id. + + @see PaHostApiInfo +*/ +typedef enum PaHostApiTypeId +{ + paInDevelopment=0, /* use while developing support for a new host API */ + paDirectSound=1, + paMME=2, + paASIO=3, + paSoundManager=4, + paCoreAudio=5, + paOSS=7, + paALSA=8, + paAL=9, + paBeOS=10, + paWDMKS=11, + paJACK=12, + paWASAPI=13, + paAudioScienceHPI=14, + paAudioIO=15 +} PaHostApiTypeId; + + +/** A structure containing information about a particular host API. */ + +typedef struct PaHostApiInfo +{ + /** this is struct version 1 */ + int structVersion; + /** The well known unique identifier of this host API @see PaHostApiTypeId */ + PaHostApiTypeId type; + /** A textual description of the host API for display on user interfaces. */ + const char *name; + + /** The number of devices belonging to this host API. This field may be + used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate + all devices for this host API. + @see Pa_HostApiDeviceIndexToDeviceIndex + */ + int deviceCount; + + /** The default input device for this host API. The value will be a + device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice + if no default input device is available. + */ + PaDeviceIndex defaultInputDevice; + + /** The default output device for this host API. The value will be a + device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice + if no default output device is available. + */ + PaDeviceIndex defaultOutputDevice; + +} PaHostApiInfo; + + +/** Retrieve a pointer to a structure containing information about a specific + host Api. + + @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) + + @return A pointer to an immutable PaHostApiInfo structure describing + a specific host API. If the hostApi parameter is out of range or an error + is encountered, the function returns NULL. + + The returned structure is owned by the PortAudio implementation and must not + be manipulated or freed. The pointer is only guaranteed to be valid between + calls to Pa_Initialize() and Pa_Terminate(). +*/ +const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); + + +/** Convert a static host API unique identifier, into a runtime + host API index. + + @param type A unique host API identifier belonging to the PaHostApiTypeId + enumeration. + + @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, + a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + The paHostApiNotFound error code indicates that the host API specified by the + type parameter is not available. + + @see PaHostApiTypeId +*/ +PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); + + +/** Convert a host-API-specific device index to standard PortAudio device index. + This function may be used in conjunction with the deviceCount field of + PaHostApiInfo to enumerate all devices for the specified host API. + + @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) + + @param hostApiDeviceIndex A valid per-host device index in the range + 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) + + @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. + + A paInvalidHostApi error code indicates that the host API index specified by + the hostApi parameter is out of range. + + A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter + is out of range. + + @see PaHostApiInfo +*/ +PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, + int hostApiDeviceIndex ); + + + +/** Structure used to return information about a host error condition. +*/ +typedef struct PaHostErrorInfo{ + PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ + long errorCode; /**< the error code returned */ + const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ +}PaHostErrorInfo; + + +/** Return information about the last host error encountered. The error + information returned by Pa_GetLastHostErrorInfo() will never be modified + asynchronously by errors occurring in other PortAudio owned threads + (such as the thread that manages the stream callback.) + + This function is provided as a last resort, primarily to enhance debugging + by providing clients with access to all available error information. + + @return A pointer to an immutable structure constraining information about + the host error. The values in this structure will only be valid if a + PortAudio function has previously returned the paUnanticipatedHostError + error code. +*/ +const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); + + + +/* Device enumeration and capabilities */ + +/** Retrieve the number of available devices. The number of available devices + may be zero. + + @return A non-negative value indicating the number of available devices or, + a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. +*/ +PaDeviceIndex Pa_GetDeviceCount( void ); + + +/** Retrieve the index of the default input device. The result can be + used in the inputDevice parameter to Pa_OpenStream(). + + @return The default input device index for the default host API, or paNoDevice + if no default input device is available or an error was encountered. +*/ +PaDeviceIndex Pa_GetDefaultInputDevice( void ); + + +/** Retrieve the index of the default output device. The result can be + used in the outputDevice parameter to Pa_OpenStream(). + + @return The default output device index for the default host API, or paNoDevice + if no default output device is available or an error was encountered. + + @note + On the PC, the user can specify a default device by + setting an environment variable. For example, to use device #1. +
+ set PA_RECOMMENDED_OUTPUT_DEVICE=1
+
+ The user should first determine the available device ids by using + the supplied application "pa_devs". +*/ +PaDeviceIndex Pa_GetDefaultOutputDevice( void ); + + +/** The type used to represent monotonic time in seconds. PaTime is + used for the fields of the PaStreamCallbackTimeInfo argument to the + PaStreamCallback and as the result of Pa_GetStreamTime(). + + PaTime values have unspecified origin. + + @see PaStreamCallback, PaStreamCallbackTimeInfo, Pa_GetStreamTime +*/ +typedef double PaTime; + + +/** A type used to specify one or more sample formats. Each value indicates + a possible format for sound data passed to and from the stream callback, + Pa_ReadStream and Pa_WriteStream. + + The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 + and aUInt8 are usually implemented by all implementations. + + The floating point representation (paFloat32) uses +1.0 and -1.0 as the + maximum and minimum respectively. + + paUInt8 is an unsigned 8 bit format where 128 is considered "ground" + + The paNonInterleaved flag indicates that audio data is passed as an array + of pointers to separate buffers, one buffer for each channel. Usually, + when this flag is not used, audio data is passed as a single buffer with + all channels interleaved. + + @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo + @see paFloat32, paInt16, paInt32, paInt24, paInt8 + @see paUInt8, paCustomFormat, paNonInterleaved +*/ +typedef unsigned long PaSampleFormat; + + +#define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ +#define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ +#define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ +#define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ +#define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ +#define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ +#define paCustomFormat ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */ + +#define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */ + +/** A structure providing information and capabilities of PortAudio devices. + Devices may support input, output or both input and output. +*/ +typedef struct PaDeviceInfo +{ + int structVersion; /* this is struct version 2 */ + const char *name; + PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/ + + int maxInputChannels; + int maxOutputChannels; + + /** Default latency values for interactive performance. */ + PaTime defaultLowInputLatency; + PaTime defaultLowOutputLatency; + /** Default latency values for robust non-interactive applications (eg. playing sound files). */ + PaTime defaultHighInputLatency; + PaTime defaultHighOutputLatency; + + double defaultSampleRate; +} PaDeviceInfo; + + +/** Retrieve a pointer to a PaDeviceInfo structure containing information + about the specified device. + @return A pointer to an immutable PaDeviceInfo structure. If the device + parameter is out of range the function returns NULL. + + @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) + + @note PortAudio manages the memory referenced by the returned pointer, + the client must not manipulate or free the memory. The pointer is only + guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). + + @see PaDeviceInfo, PaDeviceIndex +*/ +const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); + + +/** Parameters for one direction (input or output) of a stream. +*/ +typedef struct PaStreamParameters +{ + /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) + specifying the device to be used or the special constant + paUseHostApiSpecificDeviceSpecification which indicates that the actual + device(s) to use are specified in hostApiSpecificStreamInfo. + This field must not be set to paNoDevice. + */ + PaDeviceIndex device; + + /** The number of channels of sound to be delivered to the + stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). + It can range from 1 to the value of maxInputChannels in the + PaDeviceInfo record for the device specified by the device parameter. + */ + int channelCount; + + /** The sample format of the buffer provided to the stream callback, + a_ReadStream() or Pa_WriteStream(). It may be any of the formats described + by the PaSampleFormat enumeration. + */ + PaSampleFormat sampleFormat; + + /** The desired latency in seconds. Where practical, implementations should + configure their latency based on these parameters, otherwise they may + choose the closest viable latency instead. Unless the suggested latency + is greater than the absolute upper limit for the device implementations + should round the suggestedLatency up to the next practical value - ie to + provide an equal or higher latency than suggestedLatency wherever possible. + Actual latency values for an open stream may be retrieved using the + inputLatency and outputLatency fields of the PaStreamInfo structure + returned by Pa_GetStreamInfo(). + @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo + */ + PaTime suggestedLatency; + + /** An optional pointer to a host api specific data structure + containing additional information for device setup and/or stream processing. + hostApiSpecificStreamInfo is never required for correct operation, + if not used it should be set to NULL. + */ + void *hostApiSpecificStreamInfo; + +} PaStreamParameters; + + +/** Return code for Pa_IsFormatSupported indicating success. */ +#define paFormatIsSupported (0) + +/** Determine whether it would be possible to open a stream with the specified + parameters. + + @param inputParameters A structure that describes the input parameters used to + open a stream. The suggestedLatency field is ignored. See PaStreamParameters + for a description of these parameters. inputParameters must be NULL for + output-only streams. + + @param outputParameters A structure that describes the output parameters used + to open a stream. The suggestedLatency field is ignored. See PaStreamParameters + for a description of these parameters. outputParameters must be NULL for + input-only streams. + + @param sampleRate The required sampleRate. For full-duplex streams it is the + sample rate for both input and output + + @return Returns 0 if the format is supported, and an error code indicating why + the format is not supported otherwise. The constant paFormatIsSupported is + provided to compare with the return value for success. + + @see paFormatIsSupported, PaStreamParameters +*/ +PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate ); + + + +/* Streaming types and functions */ + + +/** + A single PaStream can provide multiple channels of real-time + streaming audio input and output to a client application. A stream + provides access to audio hardware represented by one or more + PaDevices. Depending on the underlying Host API, it may be possible + to open multiple streams using the same device, however this behavior + is implementation defined. Portable applications should assume that + a PaDevice may be simultaneously used by at most one PaStream. + + Pointers to PaStream objects are passed between PortAudio functions that + operate on streams. + + @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, + Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, + Pa_GetStreamTime, Pa_GetStreamCpuLoad + +*/ +typedef void PaStream; + + +/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() + or Pa_OpenDefaultStream() to indicate that the stream callback will + accept buffers of any size. +*/ +#define paFramesPerBufferUnspecified (0) + + +/** Flags used to control the behavior of a stream. They are passed as + parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be + ORed together. + + @see Pa_OpenStream, Pa_OpenDefaultStream + @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, + paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags +*/ +typedef unsigned long PaStreamFlags; + +/** @see PaStreamFlags */ +#define paNoFlag ((PaStreamFlags) 0) + +/** Disable default clipping of out of range samples. + @see PaStreamFlags +*/ +#define paClipOff ((PaStreamFlags) 0x00000001) + +/** Disable default dithering. + @see PaStreamFlags +*/ +#define paDitherOff ((PaStreamFlags) 0x00000002) + +/** Flag requests that where possible a full duplex stream will not discard + overflowed input samples without calling the stream callback. This flag is + only valid for full duplex callback streams and only when used in combination + with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using + this flag incorrectly results in a paInvalidFlag error being returned from + Pa_OpenStream and Pa_OpenDefaultStream. + + @see PaStreamFlags, paFramesPerBufferUnspecified +*/ +#define paNeverDropInput ((PaStreamFlags) 0x00000004) + +/** Call the stream callback to fill initial output buffers, rather than the + default behavior of priming the buffers with zeros (silence). This flag has + no effect for input-only and blocking read/write streams. + + @see PaStreamFlags +*/ +#define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) + +/** A mask specifying the platform specific bits. + @see PaStreamFlags +*/ +#define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) + +/** + Timing information for the buffers passed to the stream callback. + + Time values are expressed in seconds and are synchronised with the time base used by Pa_GetStreamTime() for the associated stream. + + @see PaStreamCallback, Pa_GetStreamTime +*/ +typedef struct PaStreamCallbackTimeInfo{ + PaTime inputBufferAdcTime; /**< The time when the first sample of the input buffer was captured at the ADC input */ + PaTime currentTime; /**< The time when the stream callback was invoked */ + PaTime outputBufferDacTime; /**< The time when the first sample of the output buffer will output the DAC */ +} PaStreamCallbackTimeInfo; + + +/** + Flag bit constants for the statusFlags to PaStreamCallback. + + @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, + paPrimingOutput +*/ +typedef unsigned long PaStreamCallbackFlags; + +/** In a stream opened with paFramesPerBufferUnspecified, indicates that + input data is all silence (zeros) because no real data is available. In a + stream opened without paFramesPerBufferUnspecified, it indicates that one or + more zero samples have been inserted into the input buffer to compensate + for an input underflow. + @see PaStreamCallbackFlags +*/ +#define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) + +/** In a stream opened with paFramesPerBufferUnspecified, indicates that data + prior to the first sample of the input buffer was discarded due to an + overflow, possibly because the stream callback is using too much CPU time. + Otherwise indicates that data prior to one or more samples in the + input buffer was discarded. + @see PaStreamCallbackFlags +*/ +#define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) + +/** Indicates that output data (or a gap) was inserted, possibly because the + stream callback is using too much CPU time. + @see PaStreamCallbackFlags +*/ +#define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) + +/** Indicates that output data will be discarded because no room is available. + @see PaStreamCallbackFlags +*/ +#define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) + +/** Some of all of the output data will be used to prime the stream, input + data may be zero. + @see PaStreamCallbackFlags +*/ +#define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) + +/** + Allowable return values for the PaStreamCallback. + @see PaStreamCallback +*/ +typedef enum PaStreamCallbackResult +{ + paContinue=0, /**< Signal that the stream should continue invoking the callback and processing audio. */ + paComplete=1, /**< Signal that the stream should stop invoking the callback and finish once all output samples have played. */ + paAbort=2 /**< Signal that the stream should stop invoking the callback and finish as soon as possible. */ +} PaStreamCallbackResult; + + +/** + Functions of type PaStreamCallback are implemented by PortAudio clients. + They consume, process or generate audio in response to requests from an + active PortAudio stream. + + When a stream is running, PortAudio calls the stream callback periodically. + The callback function is responsible for processing buffers of audio samples + passed via the input and output parameters. + + The PortAudio stream callback runs at very high or real-time priority. + It is required to consistently meet its time deadlines. Do not allocate + memory, access the file system, call library functions or call other functions + from the stream callback that may block or take an unpredictable amount of + time to complete. + + In order for a stream to maintain glitch-free operation the callback + must consume and return audio data faster than it is recorded and/or + played. PortAudio anticipates that each callback invocation may execute for + a duration approaching the duration of frameCount audio frames at the stream + sample rate. It is reasonable to expect to be able to utilise 70% or more of + the available CPU time in the PortAudio callback. However, due to buffer size + adaption and other factors, not all host APIs are able to guarantee audio + stability under heavy CPU load with arbitrary fixed callback buffer sizes. + When high callback CPU utilisation is required the most robust behavior + can be achieved by using paFramesPerBufferUnspecified as the + Pa_OpenStream() framesPerBuffer parameter. + + @param input and @param output are either arrays of interleaved samples or; + if non-interleaved samples were requested using the paNonInterleaved sample + format flag, an array of buffer pointers, one non-interleaved buffer for + each channel. + + The format, packing and number of channels used by the buffers are + determined by parameters to Pa_OpenStream(). + + @param frameCount The number of sample frames to be processed by + the stream callback. + + @param timeInfo Timestamps indicating the ADC capture time of the first sample + in the input buffer, the DAC output time of the first sample in the output buffer + and the time the callback was invoked. + See PaStreamCallbackTimeInfo and Pa_GetStreamTime() + + @param statusFlags Flags indicating whether input and/or output buffers + have been inserted or will be dropped to overcome underflow or overflow + conditions. + + @param userData The value of a user supplied pointer passed to + Pa_OpenStream() intended for storing synthesis data etc. + + @return + The stream callback should return one of the values in the + ::PaStreamCallbackResult enumeration. To ensure that the callback continues + to be called, it should return paContinue (0). Either paComplete or paAbort + can be returned to finish stream processing, after either of these values is + returned the callback will not be called again. If paAbort is returned the + stream will finish as soon as possible. If paComplete is returned, the stream + will continue until all buffers generated by the callback have been played. + This may be useful in applications such as soundfile players where a specific + duration of output is required. However, it is not necessary to utilize this + mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also + be used to stop the stream. The callback must always fill the entire output + buffer irrespective of its return value. + + @see Pa_OpenStream, Pa_OpenDefaultStream + + @note With the exception of Pa_GetStreamCpuLoad() it is not permissible to call + PortAudio API functions from within the stream callback. +*/ +typedef int PaStreamCallback( + const void *input, void *output, + unsigned long frameCount, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ); + + +/** Opens a stream for either input, output or both. + + @param stream The address of a PaStream pointer which will receive + a pointer to the newly opened stream. + + @param inputParameters A structure that describes the input parameters used by + the opened stream. See PaStreamParameters for a description of these parameters. + inputParameters must be NULL for output-only streams. + + @param outputParameters A structure that describes the output parameters used by + the opened stream. See PaStreamParameters for a description of these parameters. + outputParameters must be NULL for input-only streams. + + @param sampleRate The desired sampleRate. For full-duplex streams it is the + sample rate for both input and output. Note that the actual sampleRate + may differ very slightly from the desired rate because of hardware limitations. + The exact rate can be queried using Pa_GetStreamInfo(). If nothing close + to the desired sampleRate is available then the open will fail and return an error. + + @param framesPerBuffer The number of frames passed to the stream callback + function, or the preferred block granularity for a blocking read/write stream. + The special value paFramesPerBufferUnspecified (0) may be used to request that + the stream callback will receive an optimal (and possibly varying) number of + frames based on host requirements and the requested latency settings. + Note: With some host APIs, the use of non-zero framesPerBuffer for a callback + stream may introduce an additional layer of buffering which could introduce + additional latency. PortAudio guarantees that the additional latency + will be kept to the theoretical minimum however, it is strongly recommended + that a non-zero framesPerBuffer value only be used when your algorithm + requires a fixed number of frames per stream callback. + + @param streamFlags Flags which modify the behavior of the streaming process. + This parameter may contain a combination of flags ORed together. Some flags may + only be relevant to certain buffer formats. + + @param streamCallback A pointer to a client supplied function that is responsible + for processing and filling input and output buffers. If this parameter is NULL + the stream will be opened in 'blocking read/write' mode. In blocking mode, + the client can receive sample data using Pa_ReadStream and write sample data + using Pa_WriteStream, the number of samples that may be read or written + without blocking is returned by Pa_GetStreamReadAvailable and + Pa_GetStreamWriteAvailable respectively. + + @param userData A client supplied pointer which is passed to the stream callback + function. It could for example, contain a pointer to instance data necessary + for processing the audio buffers. This parameter is ignored if streamCallback + is NULL. + + @return + Upon success Pa_OpenStream() returns paNoError and places a pointer to a + valid PaStream in the stream argument. The stream is inactive (stopped). + If a call to Pa_OpenStream() fails, a non-zero error code is returned (see + PaError for possible error codes) and the value of stream is invalid. + + @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, + Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable +*/ +PaError Pa_OpenStream( PaStream** stream, + const PaStreamParameters *inputParameters, + const PaStreamParameters *outputParameters, + double sampleRate, + unsigned long framesPerBuffer, + PaStreamFlags streamFlags, + PaStreamCallback *streamCallback, + void *userData ); + + +/** A simplified version of Pa_OpenStream() that opens the default input + and/or output devices. + + @param stream The address of a PaStream pointer which will receive + a pointer to the newly opened stream. + + @param numInputChannels The number of channels of sound that will be supplied + to the stream callback or returned by Pa_ReadStream. It can range from 1 to + the value of maxInputChannels in the PaDeviceInfo record for the default input + device. If 0 the stream is opened as an output-only stream. + + @param numOutputChannels The number of channels of sound to be delivered to the + stream callback or passed to Pa_WriteStream. It can range from 1 to the value + of maxOutputChannels in the PaDeviceInfo record for the default output device. + If 0 the stream is opened as an input-only stream. + + @param sampleFormat The sample format of both the input and output buffers + provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. + sampleFormat may be any of the formats described by the PaSampleFormat + enumeration. + + @param sampleRate Same as Pa_OpenStream parameter of the same name. + @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. + @param streamCallback Same as Pa_OpenStream parameter of the same name. + @param userData Same as Pa_OpenStream parameter of the same name. + + @return As for Pa_OpenStream + + @see Pa_OpenStream, PaStreamCallback +*/ +PaError Pa_OpenDefaultStream( PaStream** stream, + int numInputChannels, + int numOutputChannels, + PaSampleFormat sampleFormat, + double sampleRate, + unsigned long framesPerBuffer, + PaStreamCallback *streamCallback, + void *userData ); + + +/** Closes an audio stream. If the audio stream is active it + discards any pending buffers as if Pa_AbortStream() had been called. +*/ +PaError Pa_CloseStream( PaStream *stream ); + + +/** Functions of type PaStreamFinishedCallback are implemented by PortAudio + clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback + function. Once registered they are called when the stream becomes inactive + (ie once a call to Pa_StopStream() will not block). + A stream will become inactive after the stream callback returns non-zero, + or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio + output, if the stream callback returns paComplete, or Pa_StopStream() is called, + the stream finished callback will not be called until all generated sample data + has been played. + + @param userData The userData parameter supplied to Pa_OpenStream() + + @see Pa_SetStreamFinishedCallback +*/ +typedef void PaStreamFinishedCallback( void *userData ); + + +/** Register a stream finished callback function which will be called when the + stream becomes inactive. See the description of PaStreamFinishedCallback for + further details about when the callback will be called. + + @param stream a pointer to a PaStream that is in the stopped state - if the + stream is not stopped, the stream's finished callback will remain unchanged + and an error code will be returned. + + @param streamFinishedCallback a pointer to a function with the same signature + as PaStreamFinishedCallback, that will be called when the stream becomes + inactive. Passing NULL for this parameter will un-register a previously + registered stream finished callback function. + + @return on success returns paNoError, otherwise an error code indicating the cause + of the error. + + @see PaStreamFinishedCallback +*/ +PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); + + +/** Commences audio processing. +*/ +PaError Pa_StartStream( PaStream *stream ); + + +/** Terminates audio processing. It waits until all pending + audio buffers have been played before it returns. +*/ +PaError Pa_StopStream( PaStream *stream ); + + +/** Terminates audio processing immediately without waiting for pending + buffers to complete. +*/ +PaError Pa_AbortStream( PaStream *stream ); + + +/** Determine whether the stream is stopped. + A stream is considered to be stopped prior to a successful call to + Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. + If a stream callback returns a value other than paContinue the stream is NOT + considered to be stopped. + + @return Returns one (1) when the stream is stopped, zero (0) when + the stream is running or, a PaErrorCode (which are always negative) if + PortAudio is not initialized or an error is encountered. + + @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive +*/ +PaError Pa_IsStreamStopped( PaStream *stream ); + + +/** Determine whether the stream is active. + A stream is active after a successful call to Pa_StartStream(), until it + becomes inactive either as a result of a call to Pa_StopStream() or + Pa_AbortStream(), or as a result of a return value other than paContinue from + the stream callback. In the latter case, the stream is considered inactive + after the last buffer has finished playing. + + @return Returns one (1) when the stream is active (ie playing or recording + audio), zero (0) when not playing or, a PaErrorCode (which are always negative) + if PortAudio is not initialized or an error is encountered. + + @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped +*/ +PaError Pa_IsStreamActive( PaStream *stream ); + + + +/** A structure containing unchanging information about an open stream. + @see Pa_GetStreamInfo +*/ + +typedef struct PaStreamInfo +{ + /** this is struct version 1 */ + int structVersion; + + /** The input latency of the stream in seconds. This value provides the most + accurate estimate of input latency available to the implementation. It may + differ significantly from the suggestedLatency value passed to Pa_OpenStream(). + The value of this field will be zero (0.) for output-only streams. + @see PaTime + */ + PaTime inputLatency; + + /** The output latency of the stream in seconds. This value provides the most + accurate estimate of output latency available to the implementation. It may + differ significantly from the suggestedLatency value passed to Pa_OpenStream(). + The value of this field will be zero (0.) for input-only streams. + @see PaTime + */ + PaTime outputLatency; + + /** The sample rate of the stream in Hertz (samples per second). In cases + where the hardware sample rate is inaccurate and PortAudio is aware of it, + the value of this field may be different from the sampleRate parameter + passed to Pa_OpenStream(). If information about the actual hardware sample + rate is not available, this field will have the same value as the sampleRate + parameter passed to Pa_OpenStream(). + */ + double sampleRate; + +} PaStreamInfo; + + +/** Retrieve a pointer to a PaStreamInfo structure containing information + about the specified stream. + @return A pointer to an immutable PaStreamInfo structure. If the stream + parameter is invalid, or an error is encountered, the function returns NULL. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @note PortAudio manages the memory referenced by the returned pointer, + the client must not manipulate or free the memory. The pointer is only + guaranteed to be valid until the specified stream is closed. + + @see PaStreamInfo +*/ +const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); + + +/** Returns the current time in seconds for a stream according to the same clock used + to generate callback PaStreamCallbackTimeInfo timestamps. The time values are + monotonically increasing and have unspecified origin. + + Pa_GetStreamTime returns valid time values for the entire life of the stream, + from when the stream is opened until it is closed. Starting and stopping the stream + does not affect the passage of time returned by Pa_GetStreamTime. + + This time may be used for synchronizing other events to the audio stream, for + example synchronizing audio to MIDI. + + @return The stream's current time in seconds, or 0 if an error occurred. + + @see PaTime, PaStreamCallback, PaStreamCallbackTimeInfo +*/ +PaTime Pa_GetStreamTime( PaStream *stream ); + + +/** Retrieve CPU usage information for the specified stream. + The "CPU Load" is a fraction of total CPU time consumed by a callback stream's + audio processing routines including, but not limited to the client supplied + stream callback. This function does not work with blocking read/write streams. + + This function may be called from the stream callback function or the + application. + + @return + A floating point value, typically between 0.0 and 1.0, where 1.0 indicates + that the stream callback is consuming the maximum number of CPU cycles possible + to maintain real-time operation. A value of 0.5 would imply that PortAudio and + the stream callback was consuming roughly 50% of the available CPU time. The + return value may exceed 1.0. A value of 0.0 will always be returned for a + blocking read/write stream, or if an error occurs. +*/ +double Pa_GetStreamCpuLoad( PaStream* stream ); + + +/** Read samples from an input stream. The function doesn't return until + the entire buffer has been filled - this may involve waiting for the operating + system to supply the data. + + Reading from a stream that is stopped is not currently supported. In particular, + it is not possible to drain the read buffer by calling Pa_ReadStream after + calling Pa_StopStream. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @param buffer A pointer to a buffer of sample frames. The buffer contains + samples in the format specified by the inputParameters->sampleFormat field + used to open the stream, and the number of channels specified by + inputParameters->numChannels. If non-interleaved samples were requested using + the paNonInterleaved sample format flag, buffer is a pointer to the first element + of an array of buffer pointers, one non-interleaved buffer for each channel. + + @param frames The number of frames to be read into buffer. This parameter + is not constrained to a specific range, however high performance applications + will want to match this parameter to the framesPerBuffer parameter used + when opening the stream. + + @return On success PaNoError will be returned, or PaInputOverflowed if input + data was discarded by PortAudio after the previous call and before this call. +*/ +PaError Pa_ReadStream( PaStream* stream, + void *buffer, + unsigned long frames ); + + +/** Write samples to an output stream. This function doesn't return until the + entire buffer has been written - this may involve waiting for the operating + system to consume the data. + + Writing to a stream that is stopped is not currently supported. In particular, + it is not possible to prefill the write buffer by calling Pa_WriteStream + prior to calling Pa_StartStream. + + @param stream A pointer to an open stream previously created with Pa_OpenStream. + + @param buffer A pointer to a buffer of sample frames. The buffer contains + samples in the format specified by the outputParameters->sampleFormat field + used to open the stream, and the number of channels specified by + outputParameters->numChannels. If non-interleaved samples were requested using + the paNonInterleaved sample format flag, buffer is a pointer to the first element + of an array of buffer pointers, one non-interleaved buffer for each channel. + + @param frames The number of frames to be written from buffer. This parameter + is not constrained to a specific range, however high performance applications + will want to match this parameter to the framesPerBuffer parameter used + when opening the stream. + + @return On success PaNoError will be returned, or paOutputUnderflowed if + additional output data was inserted after the previous call and before this + call. +*/ +PaError Pa_WriteStream( PaStream* stream, + const void *buffer, + unsigned long frames ); + + +/** Retrieve the number of frames that can be read from the stream without + waiting. + + When the stream is stopped the return value of Pa_GetStreamReadAvailable is not + defined. + + @return Returns a non-negative value representing the maximum number of frames + that can be read from the stream without blocking or busy waiting or, a + PaErrorCode (which are always negative) if PortAudio is not initialized or an + error is encountered. +*/ +signed long Pa_GetStreamReadAvailable( PaStream* stream ); + + +/** Retrieve the number of frames that can be written to the stream without + waiting. + + When the stream is stopped the return value of Pa_GetStreamWriteAvailable is not + defined. + + @return Returns a non-negative value representing the maximum number of frames + that can be written to the stream without blocking or busy waiting or, a + PaErrorCode (which are always negative) if PortAudio is not initialized or an + error is encountered. +*/ +signed long Pa_GetStreamWriteAvailable( PaStream* stream ); + + +/* Miscellaneous utilities */ + + +/** Retrieve the size of a given sample format in bytes. + + @return The size in bytes of a single sample in the specified format, + or paSampleFormatNotSupported if the format is not supported. +*/ +PaError Pa_GetSampleSize( PaSampleFormat format ); + + +/** Put the caller to sleep for at least 'msec' milliseconds. This function is + provided only as a convenience for authors of portable code (such as the tests + and examples in the PortAudio distribution.) + + The function may sleep longer than requested so don't rely on this for accurate + musical timing. +*/ +void Pa_Sleep( long msec ); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PORTAUDIO_H */ diff --git a/ChaosDataPlayer/qcustomplot.cpp b/ChaosDataPlayer/qcustomplot.cpp new file mode 100644 index 0000000..047e30c --- /dev/null +++ b/ChaosDataPlayer/qcustomplot.cpp @@ -0,0 +1,35496 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2021 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 29.03.21 ** +** Version: 2.1.0 ** +****************************************************************************/ + +#include "qcustomplot.h" + + +/* including file 'src/vector2d.cpp' */ +/* modified 2021-03-29T02:30:44, size 7973 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPVector2D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPVector2D + \brief Represents two doubles as a mathematical 2D vector + + This class acts as a replacement for QVector2D with the advantage of double precision instead of + single, and some convenience methods tailored for the QCustomPlot library. +*/ + +/* start documentation of inline functions */ + +/*! \fn void QCPVector2D::setX(double x) + + Sets the x coordinate of this vector to \a x. + + \see setY +*/ + +/*! \fn void QCPVector2D::setY(double y) + + Sets the y coordinate of this vector to \a y. + + \see setX +*/ + +/*! \fn double QCPVector2D::length() const + + Returns the length of this vector. + + \see lengthSquared +*/ + +/*! \fn double QCPVector2D::lengthSquared() const + + Returns the squared length of this vector. In some situations, e.g. when just trying to find the + shortest vector of a group, this is faster than calculating \ref length, because it avoids + calculation of a square root. + + \see length +*/ + +/*! \fn double QCPVector2D::angle() const + + Returns the angle of the vector in radians. The angle is measured between the positive x line and + the vector, counter-clockwise in a mathematical coordinate system (y axis upwards positive). In + screen/widget coordinates where the y axis is inverted, the angle appears clockwise. +*/ + +/*! \fn QPoint QCPVector2D::toPoint() const + + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point + information. + + \see toPointF +*/ + +/*! \fn QPointF QCPVector2D::toPointF() const + + Returns a QPointF which has the x and y coordinates of this vector. + + \see toPoint +*/ + +/*! \fn bool QCPVector2D::isNull() const + + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y + coordinates, i.e. if both are binary equal to 0. +*/ + +/*! \fn QCPVector2D QCPVector2D::perpendicular() const + + Returns a vector perpendicular to this vector, with the same length. +*/ + +/*! \fn double QCPVector2D::dot() const + + Returns the dot/scalar product of this vector with the specified vector \a vec. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates to 0. +*/ +QCPVector2D::QCPVector2D() : + mX(0), + mY(0) +{ +} + +/*! + Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified + values. +*/ +QCPVector2D::QCPVector2D(double x, double y) : + mX(x), + mY(y) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPoint &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPointF &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Normalizes this vector. After this operation, the length of the vector is equal to 1. + + If the vector has both entries set to zero, this method does nothing. + + \see normalized, length, lengthSquared +*/ +void QCPVector2D::normalize() +{ + if (mX == 0.0 && mY == 0.0) return; + const double lenInv = 1.0/length(); + mX *= lenInv; + mY *= lenInv; +} + +/*! + Returns a normalized version of this vector. The length of the returned vector is equal to 1. + + If the vector has both entries set to zero, this method returns the vector unmodified. + + \see normalize, length, lengthSquared +*/ +QCPVector2D QCPVector2D::normalized() const +{ + if (mX == 0.0 && mY == 0.0) return *this; + const double lenInv = 1.0/length(); + return QCPVector2D(mX*lenInv, mY*lenInv); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a start and \a end. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const +{ + const QCPVector2D v(end-start); + const double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + const double mu = v.dot(*this-start)/vLengthSqr; + if (mu < 0) + return (*this-start).lengthSquared(); + else if (mu > 1) + return (*this-end).lengthSquared(); + else + return ((start + mu*v)-*this).lengthSquared(); + } else + return (*this-start).lengthSquared(); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a line. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QLineF &line) const +{ + return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); +} + +/*! + Returns the shortest distance of this vector (interpreted as a point) to the infinite straight + line given by a \a base point and a \a direction vector. + + \see distanceSquaredToLine +*/ +double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const +{ + return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); +} + +/*! + Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a + factor. +*/ +QCPVector2D &QCPVector2D::operator*=(double factor) +{ + mX *= factor; + mY *= factor; + return *this; +} + +/*! + Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a + divisor. +*/ +QCPVector2D &QCPVector2D::operator/=(double divisor) +{ + mX /= divisor; + mY /= divisor; + return *this; +} + +/*! + Adds the given \a vector to this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) +{ + mX += vector.mX; + mY += vector.mY; + return *this; +} + +/*! + subtracts the given \a vector from this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) +{ + mX -= vector.mX; + mY -= vector.mY; + return *this; +} +/* end of 'src/vector2d.cpp' */ + + +/* including file 'src/painter.cpp' */ +/* modified 2021-03-29T02:30:44, size 8656 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} +/* end of 'src/painter.cpp' */ + + +/* including file 'src/paintbuffer.cpp' */ +/* modified 2021-03-29T02:30:44, size 18915 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPaintBuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPaintBuffer + \brief The abstract base class for paint buffers, which define the rendering backend + + This abstract base class defines the basic interface that a paint buffer needs to provide in + order to be usable by QCustomPlot. + + A paint buffer manages both a surface to draw onto, and the matching paint device. The size of + the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref + QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the + painting is complete, \ref donePainting is called, so the paint buffer implementation can do + clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color + using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the + previous frame. + + The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular + software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and + frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. + They are used automatically if \ref QCustomPlot::setOpenGl is enabled. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 + + Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the + responsibility to delete the painter after the painting operations are complete is given to the + caller of this method. + + Once you are done using the painter, delete the painter and call \ref donePainting. + + While a painter generated with this method is active, you must not call \ref setSize, \ref + setDevicePixelRatio or \ref clear. + + This method may return 0, if a painter couldn't be activated on the buffer. This usually + indicates a problem with the respective painting backend. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 + + Draws the contents of this buffer with the provided \a painter. This is the method that is used + to finally join all paint buffers and draw them onto the screen. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 + + Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the + named color \c Qt::transparent. + + This method must not be called if there is currently a painter (acquired with \ref startPainting) + active. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 + + Reallocates the internal buffer with the currently configured size (\ref setSize) and device + pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those + properties are changed on this paint buffer. + + \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method + in their constructor, to perform the first allocation (this can not be done by the base class + because calling pure virtual methods in base class constructors is not possible). +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of inline functions */ + +/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() + + If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, + call this method as soon as you are done with the painting operations and have deleted the + painter. + + paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The + default implementation does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. + + Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. +*/ +QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : + mSize(size), + mDevicePixelRatio(devicePixelRatio), + mInvalidated(true) +{ +} + +QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() +{ +} + +/*! + Sets the paint buffer size. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + If \a size is already the current buffer size, this method does nothing. +*/ +void QCPAbstractPaintBuffer::setSize(const QSize &size) +{ + if (mSize != size) + { + mSize = size; + reallocateBuffer(); + } +} + +/*! + Sets the invalidated flag to \a invalidated. + + This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer + instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered + layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, + QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also + replots them, instead of only the layer on which the replot was called. + + The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers + were added or removed from this buffer, or if they were reordered. It is set to false as soon as + all associated \ref QCPLayer instances are drawn onto the buffer. + + Under normal circumstances, it is not necessary to manually call this method. +*/ +void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) +{ + mInvalidated = invalidated; +} + +/*! + Sets the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. + The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + \note This method is only available for Qt versions 5.4 and higher. +*/ +void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mDevicePixelRatio = ratio; + reallocateBuffer(); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; +#endif + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferPixmap + \brief A paint buffer based on QPixmap, using software raster rendering + + This paint buffer is the default and fall-back paint buffer which uses software rendering and + QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. +*/ + +/*! + Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if + applicable. +*/ +QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : + QCPAbstractPaintBuffer(size, devicePixelRatio) +{ + QCPPaintBufferPixmap::reallocateBuffer(); +} + +QCPPaintBufferPixmap::~QCPPaintBufferPixmap() +{ +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferPixmap::startPainting() +{ + QCPPainter *result = new QCPPainter(&mBuffer); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + result->setRenderHint(QPainter::HighQualityAntialiasing); +#endif + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::draw(QCPPainter *painter) const +{ + if (painter && painter->isActive()) + painter->drawPixmap(0, 0, mBuffer); + else + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::clear(const QColor &color) +{ + mBuffer.fill(color); +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::reallocateBuffer() +{ + setInvalidated(); + if (!qFuzzyCompare(1.0, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBuffer = QPixmap(mSize*mDevicePixelRatio); + mBuffer.setDevicePixelRatio(mDevicePixelRatio); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; + mBuffer = QPixmap(mSize); +#endif + } else + { + mBuffer = QPixmap(mSize); + } +} + + +#ifdef QCP_OPENGL_PBUFFER +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlPbuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlPbuffer + \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. + (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a + devicePixelRatio, if applicable. + + The parameter \a multisamples defines how many samples are used per pixel. Higher values thus + result in higher quality antialiasing. If the specified \a multisamples value exceeds the + capability of the graphics hardware, the highest supported multisampling is used. +*/ +QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlPBuffer(0), + mMultisamples(qMax(0, multisamples)) +{ + QCPPaintBufferGlPbuffer::reallocateBuffer(); +} + +QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlPbuffer::startPainting() +{ + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + QCPPainter *result = new QCPPainter(mGlPBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlPBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::clear(const QColor &color) +{ + if (mGlPBuffer->isValid()) + { + mGlPBuffer->makeCurrent(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlPBuffer->doneCurrent(); + } else + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::reallocateBuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; + + QGLFormat format; + format.setAlpha(true); + format.setSamples(mMultisamples); + mGlPBuffer = new QGLPixelBuffer(mSize, format); +} +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlFbo +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlFbo + \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and + higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, + if applicable. + + All frame buffer objects shall share one OpenGL context and paint device, which need to be set up + externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref + QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot + instance. +*/ +QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlContext(glContext), + mGlPaintDevice(glPaintDevice), + mGlFrameBuffer(0) +{ + QCPPaintBufferGlFbo::reallocateBuffer(); +} + +QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() +{ + if (mGlFrameBuffer) + delete mGlFrameBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlFbo::startPainting() +{ + QSharedPointer paintDevice = mGlPaintDevice.toStrongRef(); + QSharedPointer context = mGlContext.toStrongRef(); + if (!paintDevice) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return 0; + } + if (!context) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return 0; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + if (QOpenGLContext::currentContext() != context.data()) + context->makeCurrent(context->surface()); + mGlFrameBuffer->bind(); + QCPPainter *result = new QCPPainter(paintDevice.data()); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + result->setRenderHint(QPainter::HighQualityAntialiasing); +#endif + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::donePainting() +{ + if (mGlFrameBuffer && mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + else + qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlFrameBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::clear(const QColor &color) +{ + QSharedPointer context = mGlContext.toStrongRef(); + if (!context) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + + if (QOpenGLContext::currentContext() != context.data()) + context->makeCurrent(context->surface()); + mGlFrameBuffer->bind(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlFrameBuffer->release(); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::reallocateBuffer() +{ + // release and delete possibly existing framebuffer: + if (mGlFrameBuffer) + { + if (mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + delete mGlFrameBuffer; + mGlFrameBuffer = 0; + } + + QSharedPointer paintDevice = mGlPaintDevice.toStrongRef(); + QSharedPointer context = mGlContext.toStrongRef(); + if (!paintDevice) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return; + } + if (!context) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + + // create new fbo with appropriate size: + context->makeCurrent(context->surface()); + QOpenGLFramebufferObjectFormat frameBufferFormat; + frameBufferFormat.setSamples(context->format().samples()); + frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); + if (paintDevice->size() != mSize*mDevicePixelRatio) + paintDevice->setSize(mSize*mDevicePixelRatio); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + paintDevice->setDevicePixelRatio(mDevicePixelRatio); +#endif +} +#endif // QCP_OPENGL_FBO +/* end of 'src/paintbuffer.cpp' */ + + +/* including file 'src/layer.cpp' */ +/* modified 2021-03-29T02:30:44, size 37615 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers into the paint buffer(s). + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + \section qcplayer-defaultlayers Default layers + + Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and + "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's + selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain + the default axes and legend, so they will be drawn above plottables. In the middle, there is the + "main" layer. It is initially empty and set as the current layer (see + QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this + layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong + tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind + everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of + course, the layer affiliation of the individual objects can be changed as required (\ref + QCPLayerable::setLayer). + + \section qcplayer-ordering Controlling the rendering order via layers + + Controlling the ordering of layerables in the plot is easy: Create a new layer in the position + you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the + current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the + objects normally. They will be placed on the new layer automatically, due to the current layer + setting. Alternatively you could have also ignored the current layer setting and just moved the + objects with \ref QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. + + \section qcplayer-buffering Replotting only a specific layer + + If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific + layer by calling \ref replot. In certain situations this can provide better replot performance, + compared with a full replot of all layers. Upon creation of a new layer, the layer mode is + initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref + QCustomPlot instance is the "overlay" layer, containing the selection rect. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true), + mMode(lmLogical) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(nullptr); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or nullptr beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! + Sets the rendering mode of this layer. + + If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by + the parent QCustomPlot instance. This means it may be replotted individually by calling \ref + QCPLayer::replot, without needing to replot all other layers. + + Layers which are set to \ref lmLogical (the default) are used only to define the rendering order + and can't be replotted individually. + + Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the + layers below, above and for the layer itself. This increases the memory consumption and + (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So + you should carefully choose which layers benefit from having their own paint buffer. A typical + example would be a layer which contains certain layerables (e.g. items) that need to be changed + and thus replotted regularly, while all other layerables on other layers stay static. By default, + only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection + rect. + + \see replot +*/ +void QCPLayer::setMode(QCPLayer::LayerMode mode) +{ + if (mMode != mode) + { + mMode = mode; + if (QSharedPointer pb = mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + } +} + +/*! \internal + + Draws the contents of this layer with the provided \a painter. + + \see replot, drawToPaintBuffer +*/ +void QCPLayer::draw(QCPPainter *painter) +{ + foreach (QCPLayerable *child, mChildren) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } +} + +/*! \internal + + Draws the contents of this layer into the paint buffer which is associated with this layer. The + association is established by the parent QCustomPlot, which manages all paint buffers (see \ref + QCustomPlot::setupPaintBuffers). + + \see draw +*/ +void QCPLayer::drawToPaintBuffer() +{ + if (QSharedPointer pb = mPaintBuffer.toStrongRef()) + { + if (QCPPainter *painter = pb->startPainting()) + { + if (painter->isActive()) + draw(painter); + else + qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; + delete painter; + pb->donePainting(); + } else + qDebug() << Q_FUNC_INFO << "paint buffer returned nullptr painter"; + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; +} + +/*! + If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only + the layerables on this specific layer, without the need to replot all other layers (as a call to + \ref QCustomPlot::replot would do). + + QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering + or any layerable-layer-association has changed since the last full replot and any other paint + buffers were thus invalidated. + + If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on + the parent QCustomPlot instance. + + \see draw +*/ +void QCPLayer::replot() +{ + if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) + { + if (QSharedPointer pb = mPaintBuffer.toStrongRef()) + { + pb->clear(Qt::transparent); + drawToPaintBuffer(); + pb->setInvalidated(false); // since layer is lmBuffered, we know only this layer is on buffer and we can reset invalidated flag + mParentPlot->update(); + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; + } else + mParentPlot->replot(); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + if (QSharedPointer pb = mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (mChildren.removeOne(layerable)) + { + if (QSharedPointer pb = mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return \c + nullptr. + + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only + the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide \c nullptr as \a plot. In that case, you should assign a parent plot at + a later time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(nullptr), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = nullptr; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of this layerable's layer into account. This is the method that is consulted to decide + whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the \ref selectEvent/\ref deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + In the case of 1D Plottables (\ref QCPAbstractPlottable1D, like \ref QCPGraph or \ref QCPBars) \a + details will be set to a \ref QCPDataSelection, describing the closest data point to \a pos. + + You may pass \c nullptr as \a details to indicate that you are not interested in those selection + details. + + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions, + QCPAbstractPlottable1D::selectTestRect +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed \c nullptr in the constructor. It can not be used to move a layerable from one QCustomPlot + to another one. + + Note that, unlike when passing a non \c nullptr parent plot in the constructor, this function + does not make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when \c nullptr was passed as parent plot in the constructor, + and the parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return {}; +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + +/*! + This event gets called when the user presses a mouse button while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + QCustomPlot uses an event propagation system that works the same as Qt's system. If your + layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in + its reimplementation, the event will be propagated to the next layerable in the stacking order. + + Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and + will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse + interaction (a "mouse interaction" in this context ends with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user moves the mouse while holding a mouse button, after this + layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occurred, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user releases the mouse button, after this layerable has become + the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occurred, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user presses the mouse button a second time in a double-click, + while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a + preceding call to \ref selectTest. + + The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the + case of a double-click, the event succession is + pressEvent – releaseEvent – doubleClickEvent – releaseEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, + it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent + and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends + with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent +*/ +void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user turns the mouse scroll wheel while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). + + The \c event->angleDelta() indicates how far the mouse wheel was turned, which is usually +/- 120 + for single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may + accumulate to one event, making the delta larger. On the other hand, if the wheel has very smooth + steps or none at all, the delta may be smaller. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent +*/ +void QCPLayerable::wheelEvent(QWheelEvent *event) +{ + event->ignore(); +} +/* end of 'src/layer.cpp' */ + + +/* including file 'src/axis/range.cpp' */ +/* modified 2021-03-29T02:30:44, size 12221 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/* start of documentation of inline functions */ + +/*! \fn double QCPRange::size() const + + Returns the size of the range, i.e. \a upper-\a lower +*/ + +/*! \fn double QCPRange::center() const + + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ + +/*! \fn void QCPRange::normalize() + + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are + swapped. +*/ + +/*! \fn bool QCPRange::contains(double value) const + + Returns true when \a value lies within or exactly on the borders of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end of documentation of inline functions */ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + + \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining underflowing ranges. + + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + + \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining overflowing ranges. + + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + + Constructs a range with the specified \a lower and \a upper values. + + The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically + smaller than \a upper, they will be swapped. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! \overload + + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, it will be replaced by the respective bound + of \a otherRange. + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower || qIsNaN(lower)) + lower = otherRange.lower; + if (upper < otherRange.upper || qIsNaN(upper)) + upper = otherRange.upper; +} + +/*! \overload + + Expands this range such that \a includeCoord is contained in the new range. It is assumed that + this range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the respective bound will be set to \a + includeCoord. + + If \a includeCoord is already inside the current range, this function does nothing. + + \see expand +*/ +void QCPRange::expand(double includeCoord) +{ + if (lower > includeCoord || qIsNaN(lower)) + lower = includeCoord; + if (upper < includeCoord || qIsNaN(upper)) + upper = includeCoord; +} + + +/*! \overload + + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be taken from + \a otherRange. + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! \overload + + Returns an expanded range that includes the specified \a includeCoord. It is assumed that this + range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a + includeCoord. + + \see expand +*/ +QCPRange QCPRange::expanded(double includeCoord) const +{ + QCPRange result = *this; + result.expand(includeCoord); + return result; +} + +/*! + Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a + upperBound. If possible, the size of the current range is preserved in the process. + + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref + QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref + QCPRange::maxRange. +*/ +QCPRange QCPRange::bounded(double lowerBound, double upperBound) const +{ + if (lowerBound > upperBound) + qSwap(lowerBound, upperBound); + + QCPRange result(lower, upper); + if (result.lower < lowerBound) + { + result.lower = lowerBound; + result.upper = lowerBound + size(); + if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.upper = upperBound; + } else if (result.upper > upperBound) + { + result.upper = upperBound; + result.lower = upperBound - size(); + if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.lower = lowerBound; + } + + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper -maxRange && + upper < maxRange && + qAbs(lower-upper) > minRange && + qAbs(lower-upper) < maxRange && + !(lower > 0 && qIsInf(upper/lower)) && + !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return (range.lower > -maxRange && + range.upper < maxRange && + qAbs(range.lower-range.upper) > minRange && + qAbs(range.lower-range.upper) < maxRange && + !(range.lower > 0 && qIsInf(range.upper/range.lower)) && + !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} +/* end of 'src/axis/range.cpp' */ + + +/* including file 'src/selection.cpp' */ +/* modified 2021-03-29T02:30:44, size 21837 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataRange +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataRange + \brief Describes a data range given by begin and end index + + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index + of a contiguous set of data points. The \a end index corresponds to the data point just after the + last data point of the data range, like in standard iterators. + + Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and + modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is + used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref + QCPDataSelection is thus used. + + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, + e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref + contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be + used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding + \ref QCPDataSelection. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and + QCPDataRange. + + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval + in floating point plot coordinates, e.g. the current axis range. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataRange::size() const + + Returns the number of data points described by this data range. This is equal to the end index + minus the begin index. + + \see length +*/ + +/*! \fn int QCPDataRange::length() const + + Returns the number of data points described by this data range. Equivalent to \ref size. +*/ + +/*! \fn void QCPDataRange::setBegin(int begin) + + Sets the begin of this data range. The \a begin index points to the first data point that is part + of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setEnd +*/ + +/*! \fn void QCPDataRange::setEnd(int end) + + Sets the end of this data range. The \a end index points to the data point just after the last + data point that is part of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setBegin +*/ + +/*! \fn bool QCPDataRange::isValid() const + + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and + an end index greater or equal to the begin index. + + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods + (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's + methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary + invalid begin/end values while manipulating the range. An invalid range is not necessarily empty + (\ref isEmpty), since its \ref length can be negative and thus non-zero. +*/ + +/*! \fn bool QCPDataRange::isEmpty() const + + Returns whether this range is empty, i.e. whether its begin index equals its end index. + + \see size, length +*/ + +/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const + + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end + indices, respectively. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataRange, with begin and end set to 0. +*/ +QCPDataRange::QCPDataRange() : + mBegin(0), + mEnd(0) +{ +} + +/*! + Creates a QCPDataRange, initialized with the specified \a begin and \a end. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). +*/ +QCPDataRange::QCPDataRange(int begin, int end) : + mBegin(begin), + mEnd(end) +{ +} + +/*! + Returns a data range that matches this data range, except that parts exceeding \a other are + excluded. + + This method is very similar to \ref intersection, with one distinction: If this range and the \a + other range share no intersection, the returned data range will be empty with begin and end set + to the respective boundary side of \a other, at which this range is residing. (\ref intersection + would just return a range with begin and end set to 0.) +*/ +QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const +{ + QCPDataRange result(intersection(other)); + if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value + { + if (mEnd <= other.mBegin) + result = QCPDataRange(other.mBegin, other.mBegin); + else + result = QCPDataRange(other.mEnd, other.mEnd); + } + return result; +} + +/*! + Returns a data range that contains both this data range as well as \a other. +*/ +QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const +{ + return {qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)}; +} + +/*! + Returns the data range which is contained in both this data range and \a other. + + This method is very similar to \ref bounded, with one distinction: If this range and the \a other + range share no intersection, the returned data range will be empty with begin and end set to 0. + (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, + depending on which side this range is on.) + + \see QCPDataSelection::intersection +*/ +QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const +{ + QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); + if (result.isValid()) + return result; + else + return {}; +} + +/*! + Returns whether this data range and \a other share common data points. + + \see intersection, contains +*/ +bool QCPDataRange::intersects(const QCPDataRange &other) const +{ + return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || + (mEnd <= other.mBegin && mEnd < other.mEnd) ); +} + +/*! + Returns whether all data points of \a other are also contained inside this data range. + + \see intersects +*/ +bool QCPDataRange::contains(const QCPDataRange &other) const +{ + return mBegin <= other.mBegin && mEnd >= other.mEnd; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataSelection +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataSelection + \brief Describes a data set by holding multiple QCPDataRange instances + + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly + disjoint) set of data selection. + + The data selection can be modified with addition and subtraction operators which take + QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and + \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. + + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange + instances. QCPDataSelection automatically simplifies when using the addition/subtraction + operators. The only case when \ref simplify is left to the user, is when calling \ref + addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data + ranges will be added to the selection successively and the overhead for simplifying after each + iteration shall be avoided. In this case, you should make sure to call \ref simplify after + completing the operation. + + Use \ref enforceType to bring the data selection into a state complying with the constraints for + selections defined in \ref QCP::SelectionType. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and + QCPDataRange. + + \section qcpdataselection-iterating Iterating over a data selection + + As an example, the following code snippet calculates the average value of a graph's data + \ref QCPAbstractPlottable::selection "selection": + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 + +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataSelection::dataRangeCount() const + + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref + dataRange via their index. + + \see dataRange, dataPointCount +*/ + +/*! \fn QList QCPDataSelection::dataRanges() const + + Returns all data ranges that make up the data selection. If the data selection is simplified (the + usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point + index. + + \see dataRange +*/ + +/*! \fn bool QCPDataSelection::isEmpty() const + + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection + instance. + + \see dataRangeCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataSelection. +*/ +QCPDataSelection::QCPDataSelection() +{ +} + +/*! + Creates a QCPDataSelection containing the provided \a range. +*/ +QCPDataSelection::QCPDataSelection(const QCPDataRange &range) +{ + mDataRanges.append(range); +} + +/*! + Returns true if this selection is identical (contains the same data ranges with the same begin + and end indices) to \a other. + + Note that both data selections must be in simplified state (the usual state of the selection, see + \ref simplify) for this operator to return correct results. +*/ +bool QCPDataSelection::operator==(const QCPDataSelection &other) const +{ + if (mDataRanges.size() != other.mDataRanges.size()) + return false; + for (int i=0; i= other.end()) + break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this + + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored + { + if (thisBegin >= other.begin()) // range leading segment is encompassed + { + if (thisEnd <= other.end()) // range fully encompassed, remove completely + { + mDataRanges.removeAt(i); + continue; + } else // only leading segment is encompassed, trim accordingly + mDataRanges[i].setBegin(other.end()); + } else // leading segment is not encompassed + { + if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly + { + mDataRanges[i].setEnd(other.begin()); + } else // other lies inside this range, so split range + { + mDataRanges[i].setEnd(other.begin()); + mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); + break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here + } + } + } + ++i; + } + + return *this; +} + +/*! + Returns the total number of data points contained in all data ranges that make up this data + selection. +*/ +int QCPDataSelection::dataPointCount() const +{ + int result = 0; + foreach (QCPDataRange dataRange, mDataRanges) + result += dataRange.length(); + return result; +} + +/*! + Returns the data range with the specified \a index. + + If the data selection is simplified (the usual state of the selection, see \ref simplify), the + ranges are sorted by ascending data point index. + + \see dataRangeCount +*/ +QCPDataRange QCPDataSelection::dataRange(int index) const +{ + if (index >= 0 && index < mDataRanges.size()) + { + return mDataRanges.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of range:" << index; + return {}; + } +} + +/*! + Returns a \ref QCPDataRange which spans the entire data selection, including possible + intermediate segments which are not part of the original data selection. +*/ +QCPDataRange QCPDataSelection::span() const +{ + if (isEmpty()) + return {}; + else + return {mDataRanges.first().begin(), mDataRanges.last().end()}; +} + +/*! + Adds the given \a dataRange to this data selection. This is equivalent to the += operator but + allows disabling immediate simplification by setting \a simplify to false. This can improve + performance if adding a very large amount of data ranges successively. In this case, make sure to + call \ref simplify manually, after the operation. +*/ +void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) +{ + mDataRanges.append(dataRange); + if (simplify) + this->simplify(); +} + +/*! + Removes all data ranges. The data selection then contains no data points. + + \ref isEmpty +*/ +void QCPDataSelection::clear() +{ + mDataRanges.clear(); +} + +/*! + Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent + or overlapping ranges. This can reduce the number of individual data ranges in the selection, and + prevents possible double-counting when iterating over the data points held by the data ranges. + + This method is automatically called when using the addition/subtraction operators. The only case + when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a + simplify explicitly set to false. +*/ +void QCPDataSelection::simplify() +{ + // remove any empty ranges: + for (int i=mDataRanges.size()-1; i>=0; --i) + { + if (mDataRanges.at(i).isEmpty()) + mDataRanges.removeAt(i); + } + if (mDataRanges.isEmpty()) + return; + + // sort ranges by starting value, ascending: + std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); + + // join overlapping/contiguous ranges: + int i = 1; + while (i < mDataRanges.size()) + { + if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list + { + mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); + mDataRanges.removeAt(i); + } else + ++i; + } +} + +/*! + Makes sure this data selection conforms to the specified \a type selection type. Before the type + is enforced, \ref simplify is called. + + Depending on \a type, enforcing means adding new data points that were previously not part of the + selection, or removing data points from the selection. If the current selection already conforms + to \a type, the data selection is not changed. + + \see QCP::SelectionType +*/ +void QCPDataSelection::enforceType(QCP::SelectionType type) +{ + simplify(); + switch (type) + { + case QCP::stNone: + { + mDataRanges.clear(); + break; + } + case QCP::stWhole: + { + // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) + break; + } + case QCP::stSingleData: + { + // reduce all data ranges to the single first data point: + if (!mDataRanges.isEmpty()) + { + if (mDataRanges.size() > 1) + mDataRanges = QList() << mDataRanges.first(); + if (mDataRanges.first().length() > 1) + mDataRanges.first().setEnd(mDataRanges.first().begin()+1); + } + break; + } + case QCP::stDataRange: + { + if (!isEmpty()) + mDataRanges = QList() << span(); + break; + } + case QCP::stMultipleDataRanges: + { + // this is the selection type that allows all concievable combinations of ranges, so do nothing + break; + } + } +} + +/*! + Returns true if the data selection \a other is contained entirely in this data selection, i.e. + all data point indices that are in \a other are also in this data selection. + + \see QCPDataRange::contains +*/ +bool QCPDataSelection::contains(const QCPDataSelection &other) const +{ + if (other.isEmpty()) return false; + + int otherIndex = 0; + int thisIndex = 0; + while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) + { + if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) + ++otherIndex; + else + ++thisIndex; + } + return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data range \a other. + + A common use case is to limit an unknown data selection to the valid range of a data container, + using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned + data selection without exceeding the data container's bounds. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const +{ + QCPDataSelection result; + foreach (QCPDataRange dataRange, mDataRanges) + result.addDataRange(dataRange.intersection(other), false); + result.simplify(); + return result; +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data selection \a other. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataSelection &other) const +{ + QCPDataSelection result; + for (int i=0; iorientation() == Qt::Horizontal) + return {axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())}; + else + return {axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())}; + } else + { + qDebug() << Q_FUNC_INFO << "called with axis zero"; + return {}; + } +} + +/*! + Sets the pen that will be used to draw the selection rect outline. + + \see setBrush +*/ +void QCPSelectionRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used to fill the selection rect. By default the selection rect is not + filled, i.e. \a brush is Qt::NoBrush. + + \see setPen +*/ +void QCPSelectionRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + If there is currently a selection interaction going on (\ref isActive), the interaction is + canceled. The selection rect will emit the \ref canceled signal. +*/ +void QCPSelectionRect::cancel() +{ + if (mActive) + { + mActive = false; + emit canceled(mRect, nullptr); + } +} + +/*! \internal + + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. + The default implementation sets the selection rect to active, initializes the selection rect + geometry and emits the \ref started signal. +*/ +void QCPSelectionRect::startSelection(QMouseEvent *event) +{ + mActive = true; + mRect = QRect(event->pos(), event->pos()); + emit started(event); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs + to update its geometry. The default implementation updates the rect and emits the \ref changed + signal. +*/ +void QCPSelectionRect::moveSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + emit changed(mRect, event); + layer()->replot(); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has + finished by the user releasing the mouse button. The default implementation deactivates the + selection rect and emits the \ref accepted signal. +*/ +void QCPSelectionRect::endSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + mActive = false; + emit accepted(mRect, event); +} + +/*! \internal + + This method is called by QCustomPlot when a key has been pressed by the user while the selection + rect interaction is active. The default implementation allows to \ref cancel the interaction by + hitting the escape key. +*/ +void QCPSelectionRect::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && mActive) + { + mActive = false; + emit canceled(mRect, event); + } +} + +/* inherits documentation from base class */ +void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/*! \internal + + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. + + \seebaseclassmethod +*/ +void QCPSelectionRect::draw(QCPPainter *painter) +{ + if (mActive) + { + painter->setPen(mPen); + painter->setBrush(mBrush); + painter->drawRect(mRect); + } +} +/* end of 'src/selectionrect.cpp' */ + + +/* including file 'src/layout.cpp' */ +/* modified 2021-03-29T02:30:44, size 78863 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), nullptr); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + foreach (QCPLayoutElement *el, mChildren.value(side)) + { + if (!el->autoMargins().testFlag(side)) + continue; + int m = qMax(el->calculateAutoMargin(side), QCP::getMarginValue(el->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. + + \see outerRect +*/ + +/*! \fn QRect QCPLayoutElement::outerRect() const + + Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the + margins (\ref setMargins, \ref setAutoMargins). The outer rect is used (and set via \ref + setOuterRect) by the parent \ref QCPLayout to control the size of this layout element. + + \see rect +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(nullptr), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mSizeConstraintRect(scrInnerRect), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, nullptr); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins, QCP::MarginSide +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size of this layout element. A parent layout tries to respect the \a size here + by changing row/column sizes in the layout accordingly. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size of this layout element. + + Whether this constraint applies to the inner or the outer rect can be specified with \ref + setSizeConstraintRect (see \ref rect and \ref outerRect). +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets to which rect of a layout element the size constraints apply. Size constraints can be set + via \ref setMinimumSize and \ref setMaximumSize. + + The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis + labels), whereas the inner rect (\ref rect) does not. + + \see setMinimumSize, setMaximumSize +*/ +void QCPLayoutElement::setSizeConstraintRect(SizeConstraintRect constraintRect) +{ + if (mSizeConstraintRect != constraintRect) + { + mSizeConstraintRect = constraintRect; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to \c nullptr. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). + + \see QCP::MarginSide +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + foreach (QCP::MarginSide side, sideVector) + { + if (marginGroup(side) != group) + { + QCPMarginGroup *oldGroup = marginGroup(side); + if (oldGroup) // unregister at old group + oldGroup->removeChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + const QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to, + if no manual minimum size is set. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size + (usually indirectly through \ref QCPLayout::getFinalMinimumOuterSize) to determine the minimum + allowed size of this layout element. + + A manual minimum size is considered set if it is non-zero. + + The default implementation simply returns the sum of the horizontal margins for the width and the + sum of the vertical margins for the height. Reimplementations may use their detailed knowledge + about the layout element's content to provide size hints. +*/ +QSize QCPLayoutElement::minimumOuterSizeHint() const +{ + return {mMargins.left()+mMargins.right(), mMargins.top()+mMargins.bottom()}; +} + +/*! + Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to, + if no manual maximum size is set. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts use the returned + size (usually indirectly through \ref QCPLayout::getFinalMaximumOuterSize) to determine the + maximum allowed size of this layout element. + + A manual maximum size is considered set if it is smaller than Qt's \c QWIDGETSIZE_MAX. + + The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying + no suggested maximum size. Reimplementations may use their detailed knowledge about the layout + element's content to provide size hints. +*/ +QSize QCPLayoutElement::maximumOuterSizeHint() const +{ + return {QWIDGETSIZE_MAX, QWIDGETSIZE_MAX}; +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be \c nullptr entries in the returned list. For example, QCPLayoutGrid may + have empty cells which yield \c nullptr at the respective index. +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement *el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +/*! \internal + + This virtual method is called when this layout element was moved to a different QCPLayout, or + when this layout element has changed its logical position (e.g. row and/or column) within the + same QCPLayout. Subclasses may use this to react accordingly. + + Since this method is called after the completion of the move, you can access the new parent + layout via \ref layout(). + + The default implementation does nothing. +*/ +void QCPLayoutElement::layoutChanged() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns \c + nullptr. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return \c nullptr in those cases. You may use this function + to check whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns \c nullptr. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to + reposition and resize their cells. + + Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". + + For details about this method and the update phases, see the documentation of \ref + QCPLayoutElement::update. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + el->layoutChanged(); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = nullptr; + el->setParentLayerable(nullptr); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; iminimumOuterSizeHint(); + QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0) + if (minOuter.width() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rwidth() += el->margins().left() + el->margins().right(); + if (minOuter.height() > 0 && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + minOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return {minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(), + minOuter.height() > 0 ? minOuter.height() : minOuterHint.height()}; +} + +/*! \internal + + This is a helper function for the implementation of subclasses. + + It returns the maximum size that should finally be used for the outer rect of the passed layout + element \a el. + + It takes into account whether a manual maximum size is set (\ref + QCPLayoutElement::setMaximumSize), which size constraint is set (\ref + QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum + size was set (\ref QCPLayoutElement::maximumOuterSizeHint). +*/ +QSize QCPLayout::getFinalMaximumOuterSize(const QCPLayoutElement *el) +{ + QSize maxOuterHint = el->maximumOuterSizeHint(); + QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX) + if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rwidth() += el->margins().left() + el->margins().right(); + if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect) + maxOuter.rheight() += el->margins().top() + el->margins().bottom(); + + return {maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width() : maxOuterHint.width(), + maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height() : maxOuterHint.height()}; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutGrid + \brief A layout that arranges child elements in a grid + + Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor, + \ref setRowStretchFactor) and spacing (\ref setColumnSpacing, \ref setRowSpacing). + + Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or + column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref + hasElement, that element can be retrieved with \ref element. If rows and columns that only have + empty cells shall be removed, call \ref simplify. Removal of elements is either done by just + adding the element to a different layout or by using the QCPLayout interface \ref take or \ref + remove. + + If you use \ref addElement(QCPLayoutElement*) without explicit parameters for \a row and \a + column, the grid layout will choose the position according to the current \ref setFillOrder and + the wrapping (\ref setWrap). + + Row and column insertion can be performed with \ref insertRow and \ref insertColumn. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPLayoutGrid::rowCount() const + + Returns the number of rows in the layout. + + \see columnCount +*/ + +/*! \fn int QCPLayoutGrid::columnCount() const + + Returns the number of columns in the layout. + + \see rowCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutGrid and sets default values. +*/ +QCPLayoutGrid::QCPLayoutGrid() : + mColumnSpacing(5), + mRowSpacing(5), + mWrap(0), + mFillOrder(foColumnsFirst) +{ +} + +QCPLayoutGrid::~QCPLayoutGrid() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the element in the cell in \a row and \a column. + + Returns \c nullptr if either the row/column is invalid or if the cell is empty. In those cases, a + qDebug message is printed. To check whether a cell exists and isn't empty, use \ref hasElement. + + \see addElement, hasElement +*/ +QCPLayoutElement *QCPLayoutGrid::element(int row, int column) const +{ + if (row >= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return nullptr; +} + + +/*! \overload + + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + Use the overload of this method without explicit row/column index to place the element according + to the configured fill order and wrapping settings. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (!hasElement(row, column)) + { + if (element && element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + if (element) + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + return false; +} + +/*! \overload + + Adds the \a element to the next empty cell according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first + removed from there. If necessary, the layout is expanded to hold the new element. + + Returns true if the element was added successfully. + + \see setFillOrder, setWrap, element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(QCPLayoutElement *element) +{ + int rowIndex = 0; + int colIndex = 0; + if (mFillOrder == foColumnsFirst) + { + while (hasElement(rowIndex, colIndex)) + { + ++colIndex; + if (colIndex >= mWrap && mWrap > 0) + { + colIndex = 0; + ++rowIndex; + } + } + } else + { + while (hasElement(rowIndex, colIndex)) + { + ++rowIndex; + if (rowIndex >= mWrap && mWrap > 0) + { + rowIndex = 0; + ++colIndex; + } + } + } + return addElement(rowIndex, colIndex, element); +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights, regardless of the stretch factor. (see \ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize, \ref + QCPLayoutElement::setSizeConstraintRect.) + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i tempElements; + if (rearrange) + { + tempElements.reserve(elCount); + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row= 0 && row < rowCount()) + { + if (column >= 0 && column < columnCount()) + { + switch (mFillOrder) + { + case foRowsFirst: return column*rowCount() + row; + case foColumnsFirst: return row*columnCount() + column; + } + } else + qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; + } else + qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; + return 0; +} + +/*! + Converts the linear index to row and column indices and writes the result to \a row and \a + column. + + The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the + indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices + increase top to bottom and then left to right. + + If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. + + For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, + i.e. greater or equal to zero and smaller than the current \ref elementCount. + + \see rowColToIndex +*/ +void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const +{ + row = -1; + column = -1; + const int nCols = columnCount(); + const int nRows = rowCount(); + if (nCols == 0 || nRows == 0) + return; + if (index < 0 || index >= elementCount()) + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return; + } + + switch (mFillOrder) + { + case foRowsFirst: + { + column = index / nRows; + row = index % nRows; + break; + } + case foColumnsFirst: + { + row = index / nCols; + column = index % nCols; + break; + } + } +} + +/* inherits documentation from base class */ +void QCPLayoutGrid::updateLayout() +{ + QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + { + int row, col; + indexToRowCol(index, row, col); + return mElements.at(row).at(col); + } else + return nullptr; +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + int row, col; + indexToRowCol(index, row, col); + mElements[row][col] = nullptr; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return nullptr; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + const int elCount = elementCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(elCount); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + foreach (int w, minColWidths) + result.rwidth() += w; + foreach (int h, minRowHeights) + result.rheight() += h; + result.rwidth() += qMax(0, columnCount()-1) * mColumnSpacing; + result.rheight() += qMax(0, rowCount()-1) * mRowSpacing; + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPLayoutGrid::maximumOuterSizeHint() const +{ + QVector maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + foreach (int w, maxColWidths) + result.setWidth(qMin(result.width()+w, QWIDGETSIZE_MAX)); + foreach (int h, maxRowHeights) + result.setHeight(qMin(result.height()+h, QWIDGETSIZE_MAX)); + result.rwidth() += qMax(0, columnCount()-1) * mColumnSpacing; + result.rheight() += qMax(0, rowCount()-1) * mRowSpacing; + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + if (result.height() > QWIDGETSIZE_MAX) + result.setHeight(QWIDGETSIZE_MAX); + if (result.width() > QWIDGETSIZE_MAX) + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/*! \internal + + Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights + respectively. + + The minimum height of a row is the largest minimum height of any element's outer rect in that + row. The minimum width of a column is the largest minimum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMaximumRowColSizes +*/ +void QCPLayoutGrid::getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowat(col) < minSize.width()) + (*minColWidths)[col] = minSize.width(); + if (minRowHeights->at(row) < minSize.height()) + (*minRowHeights)[row] = minSize.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element's outer rect in that + row. The maximum width of a column is the smallest maximum width of any element's outer rect in + that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowat(col) > maxSize.width()) + (*maxColWidths)[col] = maxSize.width(); + if (maxRowHeights->at(row) > maxSize.height()) + (*maxRowHeights)[row] = maxSize.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + return nullptr; +#else + return {}; +#endif + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return {}; + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; i finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(int( rect().x()+rect().width()*0.5-finalMinSize.width()*0.5 )); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(int( rect().y()+rect().height()*0.5-finalMinSize.height()*0.5 )); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return nullptr; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return nullptr; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && el->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add nullptr element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add nullptr element"; +} +/* end of 'src/layout.cpp' */ + + +/* including file 'src/lineending.cpp' */ +/* modified 2021-03-29T02:30:44, size 11189 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); + if (lengthVec.isNull()) + lengthVec = QCPVector2D(1, 0); + QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + QCPVector2D shift; + if (!qFuzzyIsNull(painter->pen().widthF()) || painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + shift = dir.normalized()*qMax(qreal(1.0), painter->pen().widthF())*qreal(0.5); + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+shift).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+shift).toPointF()); + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const +{ + draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); +} +/* end of 'src/lineending.cpp' */ + + +/* including file 'src/axis/labelpainter.cpp' */ +/* modified 2021-03-29T02:30:44, size 27296 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLabelPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLabelPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + +*/ + +const QChar QCPLabelPainterPrivate::SymbolDot(183); +const QChar QCPLabelPainterPrivate::SymbolCross(215); + +/*! + Constructs a QCPLabelPainterPrivate instance. Make sure to not create a new + instance on every redraw, to utilize the caching mechanisms. + + the \a parentPlot does not take ownership of the label painter. Make sure + to delete it appropriately. +*/ +QCPLabelPainterPrivate::QCPLabelPainterPrivate(QCustomPlot *parentPlot) : + mAnchorMode(amRectangular), + mAnchorSide(asLeft), + mAnchorReferenceType(artNormal), + mColor(Qt::black), + mPadding(0), + mRotation(0), + mSubstituteExponent(true), + mMultiplicationSymbol(QChar(215)), + mAbbreviateDecimalPowers(false), + mParentPlot(parentPlot), + mLabelCache(16) +{ + analyzeFontMetrics(); +} + +QCPLabelPainterPrivate::~QCPLabelPainterPrivate() +{ +} + +void QCPLabelPainterPrivate::setAnchorSide(AnchorSide side) +{ + mAnchorSide = side; +} + +void QCPLabelPainterPrivate::setAnchorMode(AnchorMode mode) +{ + mAnchorMode = mode; +} + +void QCPLabelPainterPrivate::setAnchorReference(const QPointF &pixelPoint) +{ + mAnchorReference = pixelPoint; +} + +void QCPLabelPainterPrivate::setAnchorReferenceType(AnchorReferenceType type) +{ + mAnchorReferenceType = type; +} + +void QCPLabelPainterPrivate::setFont(const QFont &font) +{ + if (mFont != font) + { + mFont = font; + analyzeFontMetrics(); + } +} + +void QCPLabelPainterPrivate::setColor(const QColor &color) +{ + mColor = color; +} + +void QCPLabelPainterPrivate::setPadding(int padding) +{ + mPadding = padding; +} + +void QCPLabelPainterPrivate::setRotation(double rotation) +{ + mRotation = qBound(-90.0, rotation, 90.0); +} + +void QCPLabelPainterPrivate::setSubstituteExponent(bool enabled) +{ + mSubstituteExponent = enabled; +} + +void QCPLabelPainterPrivate::setMultiplicationSymbol(QChar symbol) +{ + mMultiplicationSymbol = symbol; +} + +void QCPLabelPainterPrivate::setAbbreviateDecimalPowers(bool enabled) +{ + mAbbreviateDecimalPowers = enabled; +} + +void QCPLabelPainterPrivate::setCacheSize(int labelCount) +{ + mLabelCache.setMaxCost(labelCount); +} + +int QCPLabelPainterPrivate::cacheSize() const +{ + return mLabelCache.maxCost(); +} + +void QCPLabelPainterPrivate::drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text) +{ + double realRotation = mRotation; + + AnchorSide realSide = mAnchorSide; + // for circular axes, the anchor side is determined depending on the quadrant of tickPos with respect to mCircularReference + if (mAnchorMode == amSkewedUpright) + { + realSide = skewedAnchorSide(tickPos, 0.2, 0.3); + } else if (mAnchorMode == amSkewedRotated) // in this mode every label is individually rotated to match circle tangent + { + realSide = skewedAnchorSide(tickPos, 0, 0); + realRotation += QCPVector2D(tickPos-mAnchorReference).angle()/M_PI*180.0; + if (realRotation > 90) realRotation -= 180; + else if (realRotation < -90) realRotation += 180; + } + + realSide = rotationCorrectedSide(realSide, realRotation); // rotation angles may change the true anchor side of the label + drawLabelMaybeCached(painter, mFont, mColor, getAnchorPos(tickPos), realSide, realRotation, text); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +/* TODO: needed? +int QCPLabelPainterPrivate::size() const +{ + int result = 0; + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; ibufferDevicePixelRatio())); + result.append(QByteArray::number(mRotation)); + //result.append(QByteArray::number((int)tickLabelSide)); TODO: check whether this is really a cache-invalidating property + result.append(QByteArray::number((int)mSubstituteExponent)); + result.append(QString(mMultiplicationSymbol).toUtf8()); + result.append(mColor.name().toLatin1()+QByteArray::number(mColor.alpha(), 16)); + result.append(mFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPLabelPainterPrivate::drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + QByteArray key = cacheKey(text, color, rotation, side); + CachedLabel *cachedLabel = mLabelCache.take(QString::fromUtf8(key)); // attempt to take label from cache (don't use object() because we want ownership/prevent deletion during our operations, we re-insert it afterwards) + if (!cachedLabel) // no cached label existed, create it + { + LabelData labelData = getTickLabelData(font, color, rotation, side, text); + cachedLabel = createCachedLabel(labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + /* + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + */ + if (!labelClippedByBorder) + { + painter->drawPixmap(pos+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); // TODO: collect this in a member rect list? + } + mLabelCache.insert(QString::fromUtf8(key), cachedLabel); + } else // label caching disabled, draw text directly on surface: + { + LabelData labelData = getTickLabelData(font, color, rotation, side, text); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + /* + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + */ + if (!labelClippedByBorder) + { + drawText(painter, pos, labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + /* + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); + */ +} + +QPointF QCPLabelPainterPrivate::getAnchorPos(const QPointF &tickPos) +{ + switch (mAnchorMode) + { + case amRectangular: + { + switch (mAnchorSide) + { + case asLeft: return tickPos+QPointF(mPadding, 0); + case asRight: return tickPos+QPointF(-mPadding, 0); + case asTop: return tickPos+QPointF(0, mPadding); + case asBottom: return tickPos+QPointF(0, -mPadding); + case asTopLeft: return tickPos+QPointF(mPadding*M_SQRT1_2, mPadding*M_SQRT1_2); + case asTopRight: return tickPos+QPointF(-mPadding*M_SQRT1_2, mPadding*M_SQRT1_2); + case asBottomRight: return tickPos+QPointF(-mPadding*M_SQRT1_2, -mPadding*M_SQRT1_2); + case asBottomLeft: return tickPos+QPointF(mPadding*M_SQRT1_2, -mPadding*M_SQRT1_2); + } + } + case amSkewedUpright: + case amSkewedRotated: + { + QCPVector2D anchorNormal(tickPos-mAnchorReference); + if (mAnchorReferenceType == artTangent) + anchorNormal = anchorNormal.perpendicular(); + anchorNormal.normalize(); + return tickPos+(anchorNormal*mPadding).toPointF(); + } + } + return tickPos; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, const LabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + QPen oldPen = painter->pen(); + + // transform painter to position/rotation: + painter->translate(pos); + painter->setTransform(labelData.transform, true); + + // draw text: + painter->setFont(labelData.baseFont); + painter->setPen(QPen(labelData.color)); + if (!labelData.expPart.isEmpty()) // use superscripted exponent typesetting + { + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + /* Debug code to draw label bounding boxes, baseline, and capheight + painter->save(); + painter->setPen(QPen(QColor(0, 0, 0, 150))); + painter->drawRect(labelData.totalBounds); + const int baseline = labelData.totalBounds.height()-mLetterDescent; + painter->setPen(QPen(QColor(255, 0, 0, 150))); + painter->drawLine(QLineF(0, baseline, labelData.totalBounds.width(), baseline)); + painter->setPen(QPen(QColor(0, 0, 255, 150))); + painter->drawLine(QLineF(0, baseline-mLetterCapHeight, labelData.totalBounds.width(), baseline-mLetterCapHeight)); + painter->restore(); + */ + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); + painter->setPen(oldPen); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPLabelPainterPrivate::LabelData QCPLabelPainterPrivate::getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const +{ + LabelData result; + result.rotation = rotation; + result.side = side; + result.color = color; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (mSubstituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + + QFontMetrics baseFontMetrics(result.baseFont); + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (mAbbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += QString(mMultiplicationSymbol) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); + applyAnchorTransform(result); + result.rotatedTotalBounds = result.transform.mapRect(result.totalBounds); + + return result; +} + +void QCPLabelPainterPrivate::applyAnchorTransform(LabelData &labelData) const +{ + if (!qFuzzyIsNull(labelData.rotation)) + labelData.transform.rotate(labelData.rotation); // rotates effectively clockwise (due to flipped y axis of painter vs widget coordinate system) + + // from now on we translate in rotated label-local coordinate system. + // shift origin of coordinate system to appropriate point on label: + labelData.transform.translate(0, -labelData.totalBounds.height()+mLetterDescent+mLetterCapHeight); // shifts origin to true top of capital (or number) characters + + if (labelData.side == asLeft || labelData.side == asRight) // anchor is centered vertically + labelData.transform.translate(0, -mLetterCapHeight/2.0); + else if (labelData.side == asTop || labelData.side == asBottom) // anchor is centered horizontally + labelData.transform.translate(-labelData.totalBounds.width()/2.0, 0); + + if (labelData.side == asTopRight || labelData.side == asRight || labelData.side == asBottomRight) // anchor is at right + labelData.transform.translate(-labelData.totalBounds.width(), 0); + if (labelData.side == asBottomLeft || labelData.side == asBottom || labelData.side == asBottomRight) // anchor is at bottom (no elseif!) + labelData.transform.translate(0, -mLetterCapHeight); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +/* +void QCPLabelPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + // TODO: LabelData labelData = getTickLabelData(font, text); + // TODO: finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +*/ + +QCPLabelPainterPrivate::CachedLabel *QCPLabelPainterPrivate::createCachedLabel(const LabelData &labelData) const +{ + CachedLabel *result = new CachedLabel; + + // allocate pixmap with the correct size and pixel ratio: + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + result->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + result->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); +# else + result->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +# endif +#endif + } else + result->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + result->pixmap.fill(Qt::transparent); + + // draw the label into the pixmap + // offset is between label anchor and topleft of cache pixmap, so pixmap can be drawn at pos+offset to make the label anchor appear at pos. + // We use rotatedTotalBounds.topLeft() because rotatedTotalBounds is in a coordinate system where the label anchor is at (0, 0) + result->offset = labelData.rotatedTotalBounds.topLeft(); + QCPPainter cachePainter(&result->pixmap); + drawText(&cachePainter, -result->offset, labelData); + return result; +} + +QByteArray QCPLabelPainterPrivate::cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const +{ + return text.toUtf8()+ + QByteArray::number(color.red()+256*color.green()+65536*color.blue(), 36)+ + QByteArray::number(color.alpha()+256*(int)side, 36)+ + QByteArray::number((int)(rotation*100)%36000, 36); +} + +QCPLabelPainterPrivate::AnchorSide QCPLabelPainterPrivate::skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const +{ + QCPVector2D anchorNormal = QCPVector2D(tickPos-mAnchorReference); + if (mAnchorReferenceType == artTangent) + anchorNormal = anchorNormal.perpendicular(); + const double radius = anchorNormal.length(); + const double sideHorz = sideExpandHorz*radius; + const double sideVert = sideExpandVert*radius; + if (anchorNormal.x() > sideHorz) + { + if (anchorNormal.y() > sideVert) return asTopLeft; + else if (anchorNormal.y() < -sideVert) return asBottomLeft; + else return asLeft; + } else if (anchorNormal.x() < -sideHorz) + { + if (anchorNormal.y() > sideVert) return asTopRight; + else if (anchorNormal.y() < -sideVert) return asBottomRight; + else return asRight; + } else + { + if (anchorNormal.y() > 0) return asTop; + else return asBottom; + } + return asBottom; // should never be reached +} + +QCPLabelPainterPrivate::AnchorSide QCPLabelPainterPrivate::rotationCorrectedSide(AnchorSide side, double rotation) const +{ + AnchorSide result = side; + const bool rotateClockwise = rotation > 0; + if (!qFuzzyIsNull(rotation)) + { + if (!qFuzzyCompare(qAbs(rotation), 90)) // avoid graphical collision with anchor tangent (e.g. axis line) when rotating, so change anchor side appropriately: + { + if (side == asTop) result = rotateClockwise ? asLeft : asRight; + else if (side == asBottom) result = rotateClockwise ? asRight : asLeft; + else if (side == asTopLeft) result = rotateClockwise ? asLeft : asTop; + else if (side == asTopRight) result = rotateClockwise ? asTop : asRight; + else if (side == asBottomLeft) result = rotateClockwise ? asBottom : asLeft; + else if (side == asBottomRight) result = rotateClockwise ? asRight : asBottom; + } else // for full rotation by +/-90 degrees, other sides are more appropriate for centering on anchor: + { + if (side == asLeft) result = rotateClockwise ? asBottom : asTop; + else if (side == asRight) result = rotateClockwise ? asTop : asBottom; + else if (side == asTop) result = rotateClockwise ? asLeft : asRight; + else if (side == asBottom) result = rotateClockwise ? asRight : asLeft; + else if (side == asTopLeft) result = rotateClockwise ? asBottomLeft : asTopRight; + else if (side == asTopRight) result = rotateClockwise ? asTopLeft : asBottomRight; + else if (side == asBottomLeft) result = rotateClockwise ? asBottomRight : asTopLeft; + else if (side == asBottomRight) result = rotateClockwise ? asTopRight : asBottomLeft; + } + } + return result; +} + +void QCPLabelPainterPrivate::analyzeFontMetrics() +{ + const QFontMetrics fm(mFont); + mLetterCapHeight = fm.tightBoundingRect(QLatin1String("8")).height(); // this method is slow, that's why we query it only upon font change + mLetterDescent = fm.descent(); +} +/* end of 'src/axis/labelpainter.cpp' */ + + +/* including file 'src/axis/axisticker.cpp' */ +/* modified 2021-03-29T02:30:44, size 18688 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTicker +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTicker + \brief The base class tick generator used by QCPAxis to create tick positions and tick labels + + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions + and tick labels for the current axis range. The ticker of an axis can be set via \ref + QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple + axes can share the same ticker instance. + + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a + reasonable tick step (the separation between ticks) which results in readable tick labels. The + number of ticks that should be approximately generated can be set via \ref setTickCount. + Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either + sacrifices readability to better match the specified tick count (\ref + QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref + QCPAxisTicker::tssReadability), which is the default. + + The following more specialized axis ticker subclasses are available, see details in the + respective class documentation: + +
+ + + + + + + +
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png + \image html axisticker-time2.png
+
+ + \section axisticker-subclassing Creating own axis tickers + + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and + reimplementing some or all of the available virtual methods. + + In the simplest case you might wish to just generate different tick steps than the other tickers, + so you only reimplement the method \ref getTickStep. If you additionally want control over the + string that will be shown as tick label, reimplement \ref getTickLabel. + + If you wish to have complete control, you can generate the tick vectors and tick label vectors + yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default + implementations use the previously mentioned virtual methods \ref getTickStep and \ref + getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case + of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. + + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick + placement control is obtained by reimplementing \ref createSubTickVector. + + See the documentation of all these virtual methods in QCPAxisTicker for detailed information + about the parameters and expected return values. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTicker::QCPAxisTicker() : + mTickStepStrategy(tssReadability), + mTickCount(5), + mTickOrigin(0) +{ +} + +QCPAxisTicker::~QCPAxisTicker() +{ + +} + +/*! + Sets which strategy the axis ticker follows when choosing the size of the tick step. For the + available strategies, see \ref TickStepStrategy. +*/ +void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) +{ + mTickStepStrategy = strategy; +} + +/*! + Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count + is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with + the requested number of ticks. + + Whether the readability has priority over meeting the requested \a count can be specified with + \ref setTickStepStrategy. +*/ +void QCPAxisTicker::setTickCount(int count) +{ + if (count > 0) + mTickCount = count; + else + qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; +} + +/*! + Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a + concept and doesn't need to be inside the currently visible axis range. + + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick + step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be + {-4, 1, 6, 11, 16,...}. +*/ +void QCPAxisTicker::setTickOrigin(double origin) +{ + mTickOrigin = origin; +} + +/*! + This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), + tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). + + The ticks are generated for the specified \a range. The generated labels typically follow the + specified \a locale, \a formatChar and number \a precision, however this might be different (or + even irrelevant) for certain QCPAxisTicker subclasses. + + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. + The output parameters \a subTicks and \a tickLabels are optional (set them to \c nullptr if not + needed) and are respectively filled with sub tick coordinates, and tick label strings belonging + to \a ticks by index. +*/ +void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) +{ + // generate (major) ticks: + double tickStep = getTickStep(range); + ticks = createTickVector(tickStep, range); + trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) + + // generate sub ticks between major ticks: + if (subTicks) + { + if (!ticks.isEmpty()) + { + *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); + trimTicks(range, *subTicks, false); + } else + *subTicks = QVector(); + } + + // finally trim also outliers (no further clipping happens in axis drawing): + trimTicks(range, ticks, false); + // generate labels for visible ticks if requested: + if (tickLabels) + *tickLabels = createLabelVector(ticks, locale, formatChar, precision); +} + +/*! \internal + + Takes the entire currently visible axis range and returns a sensible tick step in + order to provide readable tick labels as well as a reasonable number of tick counts (see \ref + setTickCount, \ref setTickStepStrategy). + + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default + implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper + function. +*/ +double QCPAxisTicker::getTickStep(const QCPRange &range) +{ + double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return cleanMantissa(exactStep); +} + +/*! \internal + + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns + an appropriate number of sub ticks for that specific tick step. + + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. +*/ +int QCPAxisTicker::getSubTickCount(double tickStep) +{ + int result = 1; // default to 1, if no proper value can be found + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(getMantissa(tickStep), &intPartf); + intPart = int(intPartf); + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + This method returns the tick label string as it should be printed under the \a tick coordinate. + If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a + precision. + + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is + enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will + be formatted accordingly using multiplication symbol and superscript during rendering of the + label automatically. +*/ +QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + return locale.toString(tick, formatChar.toLatin1(), precision); +} + +/*! \internal + + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a + subTickCount sub ticks between each tick pair given in \a ticks. + + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should + reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to + base its result on \a subTickCount or \a ticks. +*/ +QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) +{ + QVector result; + if (subTickCount <= 0 || ticks.size() < 2) + return result; + + result.reserve((ticks.size()-1)*subTickCount); + for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + // Generate tick positions according to tickStep: + qint64 firstStep = qint64(floor((range.lower-mTickOrigin)/tickStep)); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = qint64(ceil((range.upper-mTickOrigin)/tickStep)); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = int(lastStep-firstStep+1); + if (tickcount < 0) tickcount = 0; + result.resize(tickcount); + for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) +{ + QVector result; + result.reserve(ticks.size()); + foreach (double tickCoord, ticks) + result.append(getTickLabel(tickCoord, locale, formatChar, precision)); + return result; +} + +/*! \internal + + Removes tick coordinates from \a ticks which lie outside the specified \a range. If \a + keepOneOutlier is true, it preserves one tick just outside the range on both sides, if present. + + The passed \a ticks must be sorted in ascending order. +*/ +void QCPAxisTicker::trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const +{ + bool lowFound = false; + bool highFound = false; + int lowIndex = 0; + int highIndex = -1; + + for (int i=0; i < ticks.size(); ++i) + { + if (ticks.at(i) >= range.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=ticks.size()-1; i >= 0; --i) + { + if (ticks.at(i) <= range.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (highFound && lowFound) + { + int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); + int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); + if (trimFront > 0 || trimBack > 0) + ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); + } else // all ticks are either all below or all above the range + ticks.clear(); +} + +/*! \internal + + Returns the coordinate contained in \a candidates which is closest to the provided \a target. + + This method assumes \a candidates is not empty and sorted in ascending order. +*/ +double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const +{ + if (candidates.size() == 1) + return candidates.first(); + QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); + if (it == candidates.constEnd()) + return *(it-1); + else if (it == candidates.constBegin()) + return *it; + else + return target-*(it-1) < *it-target ? *(it-1) : *it; +} + +/*! \internal + + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also + returns the magnitude of \a input as a power of 10. + + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. +*/ +double QCPAxisTicker::getMantissa(double input, double *magnitude) const +{ + const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); + if (magnitude) *magnitude = mag; + return input/mag; +} + +/*! \internal + + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How + strongly the mantissa is altered, and thus how strong the result deviates from the original \a + input, depends on the current tick step strategy (see \ref setTickStepStrategy). +*/ +double QCPAxisTicker::cleanMantissa(double input) const +{ + double magnitude; + const double mantissa = getMantissa(input, &magnitude); + switch (mTickStepStrategy) + { + case tssReadability: + { + return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; + } + case tssMeetTickCount: + { + // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 + if (mantissa <= 5.0) + return int(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 + else + return int(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 + } + } + return input; +} +/* end of 'src/axis/axisticker.cpp' */ + + +/* including file 'src/axis/axistickerdatetime.cpp' */ +/* modified 2021-03-29T02:30:44, size 18829 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerDateTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerDateTime + \brief Specialized axis ticker for calendar dates and times as axis ticks + + \image html axisticker-datetime.png + + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The + plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 + UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods + with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime + by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey + and \ref keyToDateTime conveniently perform this conversion achieving a precision of one + millisecond on all Qt versions. + + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. + If a different time spec or time zone shall be used for the tick label appearance, see \ref + setDateTimeSpec or \ref setTimeZone, respectively. + + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day + ticks. For example, if the axis range spans a few years such that there is one tick per year, + ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, + will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in + the image above: even though the number of days varies month by month, this ticker generates + ticks on the same day of each month. + + If you would like to change the date/time that is used as a (mathematical) starting date for the + ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a + QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at + 9:45 of every year. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation + + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and + milliseconds, and are not interested in the intricacies of real calendar dates with months and + (leap) years, have a look at QCPAxisTickerTime instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerDateTime::QCPAxisTickerDateTime() : + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mDateStrategy(dsNone) +{ + setTickCount(4); +} + +/*! + Sets the format in which dates and times are displayed as tick labels. For details about the \a + format string, see the documentation of QDateTime::toString(). + + Typical expressions are + + + + + + + + + + + + + + + + + + + + + + + + +
\c dThe day as a number without a leading zero (1 to 31)
\c ddThe day as a number with a leading zero (01 to 31)
\c dddThe abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().
\c ddddThe long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().
\c MThe month as a number without a leading zero (1 to 12)
\c MMThe month as a number with a leading zero (01 to 12)
\c MMMThe abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().
\c MMMMThe long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().
\c yyThe year as a two digit number (00 to 99)
\c yyyyThe year as a four digit number. If the year is negative, a minus sign is prepended, making five characters.
\c hThe hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
\c hhThe hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
\c HThe hour without a leading zero (0 to 23, even with AM/PM display)
\c HHThe hour with a leading zero (00 to 23, even with AM/PM display)
\c mThe minute without a leading zero (0 to 59)
\c mmThe minute with a leading zero (00 to 59)
\c sThe whole second, without any leading zero (0 to 59)
\c ssThe whole second, with a leading zero where applicable (00 to 59)
\c zThe fractional part of the second, to go after a decimal point, without trailing zeroes (0 to 999). Thus "s.z" reports the seconds to full available (millisecond) precision without trailing zeroes.
\c zzzThe fractional part of the second, to millisecond precision, including trailing zeroes where applicable (000 to 999).
\c AP or \c AUse AM/PM display. A/AP will be replaced by an upper-case version of either QLocale::amText() or QLocale::pmText().
\c ap or \c aUse am/pm display. a/ap will be replaced by a lower-case version of either QLocale::amText() or QLocale::pmText().
\c tThe timezone (for example "CEST")
+ + Newlines can be inserted with \c "\n", literal strings (even when containing above expressions) + by encapsulating them using single-quotes. A literal single quote can be generated by using two + consecutive single quotes in the format. + + \see setDateTimeSpec, setTimeZone +*/ +void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the time spec that is used for creating the tick labels from corresponding dates/times. + + The default value of QDateTime objects (and also QCPAxisTickerDateTime) is + Qt::LocalTime. However, if the displayed tick labels shall be given in UTC, set \a spec + to Qt::UTC. + + Tick labels corresponding to other time zones can be achieved with \ref setTimeZone (which sets + \a spec to \c Qt::TimeZone internally). Note that if \a spec is afterwards set to not be \c + Qt::TimeZone again, the \ref setTimeZone setting will be ignored accordingly. + + \see setDateTimeFormat, setTimeZone +*/ +void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) +{ + mDateTimeSpec = spec; +} + +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) +/*! + Sets the time zone that is used for creating the tick labels from corresponding dates/times. The + time spec (\ref setDateTimeSpec) is set to \c Qt::TimeZone. + + \see setDateTimeFormat, setTimeZone +*/ +void QCPAxisTickerDateTime::setTimeZone(const QTimeZone &zone) +{ + mTimeZone = zone; + mDateTimeSpec = Qt::TimeZone; +} +#endif + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, + 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which + directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(double origin) +{ + QCPAxisTicker::setTickOrigin(origin); +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) +{ + setTickOrigin(dateTimeToKey(origin)); +} + +/*! \internal + + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + Note that this tick step isn't used exactly when generating the tick vector in \ref + createTickVector, but only as a guiding value requiring some correction for each individual tick + interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day + in the month to the last day in the previous month from tick to tick, due to the non-uniform + length of months. The same problem arises with leap years. + + \seebaseclassmethod +*/ +double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + mDateStrategy = dsNone; // leaving it at dsNone means tick coordinates will not be tuned in any special way in createTickVector + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + result = cleanMantissa(result); + } else if (result < 86400*30.4375*12) // below a year + { + result = pickClosest(result, QVector() + << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range + << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range + << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + if (result > 86400*30.4375-1) // month tick intervals or larger + mDateStrategy = dsUniformDayInMonth; + else if (result > 3600*24-1) // day tick intervals or larger + mDateStrategy = dsUniformTimeInDay; + } else // more than a year, go back to normal clean mantissa algorithm but in units of years + { + const double secondsPerYear = 86400*30.4375*12; // average including leap years + result = cleanMantissa(result/secondsPerYear)*secondsPerYear; + mDateStrategy = dsUniformDayInMonth; + } + return result; +} + +/*! \internal + + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + \seebaseclassmethod +*/ +int QCPAxisTickerDateTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + case 86400*2: result = 1; break; + case 86400*5: result = 4; break; + case 86400*7: result = 6; break; + case 86400*14: result = 1; break; + case int(86400*30.4375+0.5): result = 3; break; + case int(86400*30.4375*2+0.5): result = 1; break; + case int(86400*30.4375*3+0.5): result = 2; break; + case int(86400*30.4375*6+0.5): result = 5; break; + case int(86400*30.4375*12+0.5): result = 3; break; + } + return result; +} + +/*! \internal + + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format + (\ref setDateTimeFormat), time spec (\ref setDateTimeSpec), and possibly time zone (\ref + setTimeZone). + + \seebaseclassmethod +*/ +QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + if (mDateTimeSpec == Qt::TimeZone) + return locale.toString(keyToDateTime(tick).toTimeZone(mTimeZone), mDateTimeFormat); + else + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +# else + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +# endif +} + +/*! \internal + + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain + non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) + { + if (mDateStrategy == dsUniformTimeInDay) + { + QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible + QDateTime tickDateTime; + for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day + tickDateTime = tickDateTime.addMonths(-1); + tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); + result[i] = dateTimeToKey(tickDateTime); + } + } + } + return result; +} + +/*! + A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a + QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) + + \see dateTimeToKey +*/ +QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return QDateTime::fromTime_t(key).addMSecs((key-(qint64)key)*1000); +# else + return QDateTime::fromMSecsSinceEpoch(qint64(key*1000.0)); +# endif +} + +/*! \overload + + A convenience method which turns a QDateTime object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime &dateTime) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return dateTime.toTime_t()+dateTime.time().msec()/1000.0; +# else + return dateTime.toMSecsSinceEpoch()/1000.0; +# endif +} + +/*! \overload + + A convenience method which turns a QDate object into a double value that corresponds to seconds + since Epoch (1. Jan 1970, 00:00 UTC). This is the format used + as axis coordinates by QCPAxisTickerDateTime. + + The returned value will be the start of the passed day of \a date, interpreted in the given \a + timeSpec. + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return QDateTime(date, QTime(0, 0), timeSpec).toTime_t(); +# elif QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + return QDateTime(date, QTime(0, 0), timeSpec).toMSecsSinceEpoch()/1000.0; +# else + return date.startOfDay(timeSpec).toMSecsSinceEpoch()/1000.0; +# endif +} +/* end of 'src/axis/axistickerdatetime.cpp' */ + + +/* including file 'src/axis/axistickertime.cpp' */ +/* modified 2021-03-29T02:30:44, size 11745 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerTime + \brief Specialized axis ticker for time spans in units of milliseconds to days + + \image html axisticker-time.png + + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. + + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref + setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate + zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date + and time. + + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the + largest available unit in the format specified with \ref setTimeFormat, any time spans above will + be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at + coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick + label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour + unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis + zero will carry a leading minus sign. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation + + Here is an example of a time axis providing time information in days, hours and minutes. Due to + the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker + decided to use tick steps of 12 hours: + + \image html axisticker-time2.png + + The format string for this example is + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 + + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime + instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerTime::QCPAxisTickerTime() : + mTimeFormat(QLatin1String("%h:%m:%s")), + mSmallestUnit(tuSeconds), + mBiggestUnit(tuHours) +{ + setTickCount(4); + mFieldWidth[tuMilliseconds] = 3; + mFieldWidth[tuSeconds] = 2; + mFieldWidth[tuMinutes] = 2; + mFieldWidth[tuHours] = 2; + mFieldWidth[tuDays] = 1; + + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); + mFormatPattern[tuSeconds] = QLatin1String("%s"); + mFormatPattern[tuMinutes] = QLatin1String("%m"); + mFormatPattern[tuHours] = QLatin1String("%h"); + mFormatPattern[tuDays] = QLatin1String("%d"); +} + +/*! + Sets the format that will be used to display time in the tick labels. + + The available patterns are: + - %%z for milliseconds + - %%s for seconds + - %%m for minutes + - %%h for hours + - %%d for days + + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. + + The largest unit that appears in \a format will carry all the remaining time of a certain tick + coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the + largest unit it might become larger than 59 in order to consume larger time values. If on the + other hand %%h is available, the minutes will wrap around to zero after 59 and the time will + carry to the hour digit. +*/ +void QCPAxisTickerTime::setTimeFormat(const QString &format) +{ + mTimeFormat = format; + + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest + // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) + mSmallestUnit = tuMilliseconds; + mBiggestUnit = tuMilliseconds; + bool hasSmallest = false; + for (int i = tuMilliseconds; i <= tuDays; ++i) + { + TimeUnit unit = static_cast(i); + if (mTimeFormat.contains(mFormatPattern.value(unit))) + { + if (!hasSmallest) + { + mSmallestUnit = unit; + hasSmallest = true; + } + mBiggestUnit = unit; + } + } +} + +/*! + Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick + label. If the number for the specific unit is shorter than \a width, it will be padded with an + according number of zeros to the left in order to reach the field width. + + \see setTimeFormat +*/ +void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) +{ + mFieldWidth[unit] = qMax(width, 1); +} + +/*! \internal + + Returns the tick step appropriate for time displays, depending on the provided \a range and the + smallest available time unit in the current format (\ref setTimeFormat). For example if the unit + of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) + that require sub-minute precision to be displayed correctly. + + \seebaseclassmethod +*/ +double QCPAxisTickerTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + if (mSmallestUnit == tuMilliseconds) + result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond + else // have no milliseconds available in format, so stick with 1 second tickstep + result = 1.0; + } else if (result < 3600*24) // below a day + { + // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run + QVector availableSteps; + // seconds range: + if (mSmallestUnit <= tuSeconds) + availableSteps << 1; + if (mSmallestUnit == tuMilliseconds) + availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it + else if (mSmallestUnit == tuSeconds) + availableSteps << 2; + if (mSmallestUnit <= tuSeconds) + availableSteps << 5 << 10 << 15 << 30; + // minutes range: + if (mSmallestUnit <= tuMinutes) + availableSteps << 1*60; + if (mSmallestUnit <= tuSeconds) + availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it + else if (mSmallestUnit == tuMinutes) + availableSteps << 2*60; + if (mSmallestUnit <= tuMinutes) + availableSteps << 5*60 << 10*60 << 15*60 << 30*60; + // hours range: + if (mSmallestUnit <= tuHours) + availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; + // pick available step that is most appropriate to approximate ideal step: + result = pickClosest(result, availableSteps); + } else // more than a day, go back to normal clean mantissa algorithm but in units of days + { + const double secondsPerDay = 3600*24; + result = cleanMantissa(result/secondsPerDay)*secondsPerDay; + } + return result; +} + +/*! \internal + + Returns the sub tick count appropriate for the provided \a tickStep and time displays. + + \seebaseclassmethod +*/ +int QCPAxisTickerTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + } + return result; +} + +/*! \internal + + Returns the tick label corresponding to the provided \a tick and the configured format and field + widths (\ref setTimeFormat, \ref setFieldWidth). + + \seebaseclassmethod +*/ +QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + Q_UNUSED(locale) + bool negative = tick < 0; + if (negative) tick *= -1; + double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) + double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time + + restValues[tuMilliseconds] = tick*1000; + values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; + values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; + values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; + values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; + // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) + + QString result = mTimeFormat; + for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) + { + TimeUnit iUnit = static_cast(i); + replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); + } + if (negative) + result.prepend(QLatin1Char('-')); + return result; +} + +/*! \internal + + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified + \a value, using the field width as specified with \ref setFieldWidth for the \a unit. +*/ +void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const +{ + QString valueStr = QString::number(value); + while (valueStr.size() < mFieldWidth.value(unit)) + valueStr.prepend(QLatin1Char('0')); + + text.replace(mFormatPattern.value(unit), valueStr); +} +/* end of 'src/axis/axistickertime.cpp' */ + + +/* including file 'src/axis/axistickerfixed.cpp' */ +/* modified 2021-03-29T02:30:44, size 5575 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerFixed +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerFixed + \brief Specialized axis ticker with a fixed tick step + + \image html axisticker-fixed.png + + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It + is also possible to allow integer multiples and integer powers of the specified tick step with + \ref setScaleStrategy. + + A typical application of this ticker is to make an axis only display integers, by setting the + tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. + + Another case is when a certain number has a special meaning and axis ticks should only appear at + multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi + because despite the name it is not limited to only pi symbols/values. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerFixed::QCPAxisTickerFixed() : + mTickStep(1.0), + mScaleStrategy(ssNone) +{ +} + +/*! + Sets the fixed tick interval to \a step. + + The axis ticker will only use this tick step when generating axis ticks. This might cause a very + high tick density and overlapping labels if the axis range is zoomed out. Using \ref + setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a + step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref + setTickCount). +*/ +void QCPAxisTickerFixed::setTickStep(double step) +{ + if (step > 0) + mTickStep = step; + else + qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; +} + +/*! + Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether + modifications may be applied to it before calculating the finally used tick step, such as + permitting multiples or powers. See \ref ScaleStrategy for details. + + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. +*/ +void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) +{ + mScaleStrategy = strategy; +} + +/*! \internal + + Determines the actually used tick step from the specified tick step and scale strategy (\ref + setTickStep, \ref setScaleStrategy). + + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref + ssNone, a modification of it to allow varying the number of ticks in the current axis range. + + \seebaseclassmethod +*/ +double QCPAxisTickerFixed::getTickStep(const QCPRange &range) +{ + switch (mScaleStrategy) + { + case ssNone: + { + return mTickStep; + } + case ssMultiples: + { + double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + if (exactStep < mTickStep) + return mTickStep; + else + return qint64(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; + } + case ssPowers: + { + double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return qPow(mTickStep, int(qLn(exactStep)/qLn(mTickStep)+0.5)); + } + } + return mTickStep; +} +/* end of 'src/axis/axistickerfixed.cpp' */ + + +/* including file 'src/axis/axistickertext.cpp' */ +/* modified 2021-03-29T02:30:44, size 8742 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerText +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerText + \brief Specialized axis ticker which allows arbitrary labels at specified coordinates + + \image html axisticker-text.png + + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as + coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a + time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks + and modify the tick/label data there. + + This is useful for cases where the axis represents categories rather than numerical values. + + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on + the axis range), it is a sign that you should probably create an own ticker by subclassing + QCPAxisTicker, instead of using this one. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation +*/ + +/* start of documentation of inline functions */ + +/*! \fn QMap &QCPAxisTickerText::ticks() + + Returns a non-const reference to the internal map which stores the tick coordinates and their + labels. + + You can access the map directly in order to add, remove or manipulate ticks, as an alternative to + using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerText::QCPAxisTickerText() : + mSubTickCount(0) +{ +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis + coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QMap &ticks) +{ + mTicks = ticks; +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis + coordinates, and the entries of \a labels are the respective strings that will appear as tick + labels. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QVector &positions, const QVector &labels) +{ + clear(); + addTicks(positions, labels); +} + +/*! + Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no + automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this + method. +*/ +void QCPAxisTickerText::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! + Clears all ticks. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see setTicks, addTicks, addTick +*/ +void QCPAxisTickerText::clear() +{ + mTicks.clear(); +} + +/*! + Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a + label. + + \see addTicks, setTicks, clear +*/ +void QCPAxisTickerText::addTick(double position, const QString &label) +{ + mTicks.insert(position, label); +} + +/*! \overload + + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to + the axis coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QMap &ticks) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + mTicks.unite(ticks); +#else + mTicks.insert(ticks); +#endif +} + +/*! \overload + + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to + the axis coordinates, and the entries of \a labels are the respective strings that will appear as + tick labels. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) +{ + if (positions.size() != labels.size()) + qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); + int n = qMin(positions.size(), labels.size()); + for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (mTicks.isEmpty()) + return result; + + QMap::const_iterator start = mTicks.lowerBound(range.lower); + QMap::const_iterator end = mTicks.upperBound(range.upper); + // this method should try to give one tick outside of range so proper subticks can be generated: + if (start != mTicks.constBegin()) --start; + if (end != mTicks.constEnd()) ++end; + for (QMap::const_iterator it = start; it != end; ++it) + result.append(it.key()); + + return result; +} +/* end of 'src/axis/axistickertext.cpp' */ + + +/* including file 'src/axis/axistickerpi.cpp' */ +/* modified 2021-03-29T02:30:44, size 11177 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerPi +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerPi + \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi + + \image html axisticker-pi.png + + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic + constant with a numerical value specified with \ref setPiValue and an appearance in the tick + labels specified with \ref setPiSymbol. + + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the + tick label can be configured with \ref setFractionStyle. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerPi::QCPAxisTickerPi() : + mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), + mPiValue(M_PI), + mPeriodicity(0), + mFractionStyle(fsUnicodeFractions), + mPiTickStep(0) +{ + setTickCount(4); +} + +/*! + Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick + label. + + If a space shall appear between the number and the symbol, make sure the space is contained in \a + symbol. +*/ +void QCPAxisTickerPi::setPiSymbol(QString symbol) +{ + mPiSymbol = symbol; +} + +/*! + Sets the numerical value that the symbolic constant has. + + This will be used to place the appropriate fractions of the symbol at the respective axis + coordinates. +*/ +void QCPAxisTickerPi::setPiValue(double pi) +{ + mPiValue = pi; +} + +/*! + Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the + symbolic constant. + + To disable periodicity, set \a multiplesOfPi to zero. + + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. +*/ +void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) +{ + mPeriodicity = qAbs(multiplesOfPi); +} + +/*! + Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick + labels. See \ref FractionStyle for the various options. +*/ +void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) +{ + mFractionStyle = style; +} + +/*! \internal + + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence + the numerical/fractional part preceding the symbolic constant is made to have a readable + mantissa. + + \seebaseclassmethod +*/ +double QCPAxisTickerPi::getTickStep(const QCPRange &range) +{ + mPiTickStep = range.size()/mPiValue/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + mPiTickStep = cleanMantissa(mPiTickStep); + return mPiTickStep*mPiValue; +} + +/*! \internal + + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In + consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant + reasonably, and not the total tick coordinate. + + \seebaseclassmethod +*/ +int QCPAxisTickerPi::getSubTickCount(double tickStep) +{ + return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); +} + +/*! \internal + + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The + formatting of the fraction is done according to the specified \ref setFractionStyle. The appended + symbol is specified with \ref setPiSymbol. + + \seebaseclassmethod +*/ +QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + double tickInPis = tick/mPiValue; + if (mPeriodicity > 0) + tickInPis = fmod(tickInPis, mPeriodicity); + + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) + { + // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above + int denominator = 1000; + int numerator = qRound(tickInPis*denominator); + simplifyFraction(numerator, denominator); + if (qAbs(numerator) == 1 && denominator == 1) + return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else if (numerator == 0) + return QLatin1String("0"); + else + return fractionToString(numerator, denominator) + mPiSymbol; + } else + { + if (qFuzzyIsNull(tickInPis)) + return QLatin1String("0"); + else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) + return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else + return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; + } +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure + the fraction is in irreducible form, i.e. numerator and denominator don't share any common + factors which could be cancelled. +*/ +void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const +{ + if (numerator == 0 || denominator == 0) + return; + + int num = numerator; + int denom = denominator; + while (denom != 0) // euclidean gcd algorithm + { + int oldDenom = denom; + denom = num % denom; + num = oldDenom; + } + // num is now gcd of numerator and denominator + numerator /= num; + denominator /= num; +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and returns a string representation. + The result depends on the configured fraction style (\ref setFractionStyle). + + This method is used to format the numerical/fractional part when generating tick labels. It + simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out + any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). +*/ +QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const +{ + if (denominator == 0) + { + qDebug() << Q_FUNC_INFO << "called with zero denominator"; + return QString(); + } + if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function + { + qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; + return QString::number(numerator/double(denominator)); // failsafe + } + int sign = numerator*denominator < 0 ? -1 : 1; + numerator = qAbs(numerator); + denominator = qAbs(denominator); + + if (denominator == 1) + { + return QString::number(sign*numerator); + } else + { + int integerPart = numerator/denominator; + int remainder = numerator%denominator; + if (remainder == 0) + { + return QString::number(sign*integerPart); + } else + { + if (mFractionStyle == fsAsciiFractions) + { + return QString(QLatin1String("%1%2%3/%4")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QString(QLatin1String(""))) + .arg(remainder) + .arg(denominator); + } else if (mFractionStyle == fsUnicodeFractions) + { + return QString(QLatin1String("%1%2%3")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) + .arg(unicodeFraction(remainder, denominator)); + } + } + } + return QString(); +} + +/*! \internal + + Returns the unicode string representation of the fraction given by \a numerator and \a + denominator. This is the representation used in \ref fractionToString when the fraction style + (\ref setFractionStyle) is \ref fsUnicodeFractions. + + This method doesn't use the single-character common fractions but builds each fraction from a + superscript unicode number, the unicode fraction character, and a subscript unicode number. +*/ +QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const +{ + return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); +} + +/*! \internal + + Returns the unicode string representing \a number as superscript. This is used to build + unicode fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSuperscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2070)); + + QString result; + while (number > 0) + { + const int digit = number%10; + switch (digit) + { + case 1: { result.prepend(QChar(0x00B9)); break; } + case 2: { result.prepend(QChar(0x00B2)); break; } + case 3: { result.prepend(QChar(0x00B3)); break; } + default: { result.prepend(QChar(0x2070+digit)); break; } + } + number /= 10; + } + return result; +} + +/*! \internal + + Returns the unicode string representing \a number as subscript. This is used to build unicode + fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSubscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2080)); + + QString result; + while (number > 0) + { + result.prepend(QChar(0x2080+number%10)); + number /= 10; + } + return result; +} +/* end of 'src/axis/axistickerpi.cpp' */ + + +/* including file 'src/axis/axistickerlog.cpp' */ +/* modified 2021-03-29T02:30:44, size 7890 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerLog +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerLog + \brief Specialized axis ticker suited for logarithmic axes + + \image html axisticker-log.png + + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic + axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). + + Especially in the case of a log base equal to 10 (the default), it might be desirable to have + tick labels in the form of powers of ten without mantissa display. To achieve this, set the + number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref + QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal + powers, so a format string of "eb". This will result in the following axis tick labels: + + \image html axisticker-log-powers.png + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation + + Note that the nature of logarithmic ticks imply that there exists a smallest possible tick step, + corresponding to one multiplication by the log base. If the user zooms in further than that, no + new ticks would appear, leading to very sparse or even no axis ticks on the axis. To prevent this + situation, this ticker falls back to regular tick generation if the axis range would be covered + by too few logarithmically placed ticks. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerLog::QCPAxisTickerLog() : + mLogBase(10.0), + mSubTickCount(8), // generates 10 intervals + mLogBaseLnInv(1.0/qLn(mLogBase)) +{ +} + +/*! + Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer + powers of \a base. +*/ +void QCPAxisTickerLog::setLogBase(double base) +{ + if (base > 0) + { + mLogBase = base; + mLogBaseLnInv = 1.0/qLn(mLogBase); + } else + qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; +} + +/*! + Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced + linearly to provide a better visual guide, so the sub tick density increases toward the higher + tick. + + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in + the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub + ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, + namely at 20, 30, 40, 50, 60, 70, 80 and 90. +*/ +void QCPAxisTickerLog::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! \internal + + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no + automatic sub tick count calculation necessary. + + \seebaseclassmethod +*/ +int QCPAxisTickerLog::getSubTickCount(double tickStep) +{ + Q_UNUSED(tickStep) + return mSubTickCount; +} + +/*! \internal + + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the + provided \a range. The step in which the power increases tick by tick is chosen in order to keep + the total number of ticks as close as possible to the tick count (\ref setTickCount). + + The parameter \a tickStep is ignored for the normal logarithmic ticker generation. Only when + zoomed in very far such that not enough logarithmically placed ticks would be visible, this + function falls back to the regular QCPAxisTicker::createTickVector, which then uses \a tickStep. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + if (range.lower > 0 && range.upper > 0) // positive range + { + const double baseTickCount = qLn(range.upper/range.lower)*mLogBaseLnInv; + if (baseTickCount < 1.6) // if too few log ticks would be visible in axis range, fall back to regular tick vector generation + return QCPAxisTicker::createTickVector(tickStep, range); + const double exactPowerStep = baseTickCount/double(mTickCount+1e-10); + const double newLogBase = qPow(mLogBase, qMax(int(cleanMantissa(exactPowerStep)), 1)); + double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick *= newLogBase; + result.append(currentTick); + } + } else if (range.lower < 0 && range.upper < 0) // negative range + { + const double baseTickCount = qLn(range.lower/range.upper)*mLogBaseLnInv; + if (baseTickCount < 1.6) // if too few log ticks would be visible in axis range, fall back to regular tick vector generation + return QCPAxisTicker::createTickVector(tickStep, range); + const double exactPowerStep = baseTickCount/double(mTickCount+1e-10); + const double newLogBase = qPow(mLogBase, qMax(int(cleanMantissa(exactPowerStep)), 1)); + double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick /= newLogBase; + result.append(currentTick); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; + } + + return result; +} +/* end of 'src/axis/axistickerlog.cpp' */ + + +/* including file 'src/axis/axis.cpp' */ +/* modified 2021-03-29T02:30:44, size 99883 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mSubGridVisible{}, + mAntialiasedSubGrid{}, + mAntialiasedZeroLine{}, + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mParentAxis->subTicks() && mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const int tickCount = mParentAxis->mTickVector.size(); + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + foreach (double tickCoord, mParentAxis->mSubTickVector) + { + t = mParentAxis->coordToPixel(tickCoord); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + foreach (double tickCoord, mParentAxis->mSubTickVector) + { + t = mParentAxis->coordToPixel(tickCoord); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type), pixelOrientation +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation(), pixelOrientation +*/ + +/*! \fn int QCPAxis::pixelOrientation() const + + Returns which direction points towards higher coordinate values/keys, in pixel space. + + This method returns either 1 or -1. If it returns 1, then going in the positive direction along + the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. + On the other hand, if this method returns -1, going to smaller pixel values corresponds to going + from lower to higher axis coordinates. + + For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, + without having to care about reversed or vertically aligned axes: + + \code + double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); + \endcode + + \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. +*/ + +/*! \fn QSharedPointer QCPAxis::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mTicker(new QCPAxisTicker), + mCachedMarginValid(false), + mCachedMargin(0), + mDragging(false) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. For logarithmic scales, you will + likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting + the axis ticker to an instance of \ref QCPAxisTickerLog : + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-creation + + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick + creation. + + \ref setNumberPrecision +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPAxis::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set nullptr as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. + + The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. For the 'e', 'E', and 'f' formats, + the precision set by \ref setNumberPrecision represents the number of digits after the decimal + point. For the 'g' and 'G' formats, the precision represents the maximum number of significant + digits, trailing zeroes are omitted. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPAxis::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPAxis::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/double(otherPixelSize); + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QCPRange newRange; + bool haveRange = false; + foreach (QCPAbstractPlottable *plottable, plottables()) + { + if (!plottable->realVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (plottable->keyAxis() == this) + plottableRange = plottable->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = plottable->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/double(mAxisRect->width())*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/double(mAxisRect->width())*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/double(mAxisRect->width()))*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/double(mAxisRect->width()))*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/double(mAxisRect->height())*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/double(mAxisRect->height())*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/double(mAxisRect->height()))*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/double(mAxisRect->height()))*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + foreach (QCPAbstractPlottable *plottable, mParentPlot->mPlottables) + { + if (plottable->keyAxis() == this || plottable->valueAxis() == this) + result.append(plottable); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + foreach (QCPGraph *graph, mParentPlot->mGraphs) + { + if (graph->keyAxis() == this || graph->valueAxis() == this) + result.append(graph); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + foreach (QCPAbstractItem *item, mParentPlot->mItems) + { + foreach (QCPItemPosition *position, item->positions()) + { + if (position->keyAxis() == this || position->valueAxis() == this) + { + result.append(item); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << static_cast(side); + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; + case atRight: return atLeft; + case atBottom: return atTop; + case atTop: return atBottom; + } + qDebug() << Q_FUNC_INFO << "invalid axis type"; + return atLeft; +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis + (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref + QCPAxisRect::setRangeDragAxes) + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. +*/ +void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) || + !mAxisRect->rangeDrag().testFlag(orientation()) || + !mAxisRect->rangeDragAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + mDragStartRange = mRange; + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (mDragging) + { + const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); + const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); + if (mScaleType == QCPAxis::stLinear) + { + const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); + setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); + } else if (mScaleType == QCPAxis::stLogarithmic) + { + const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); + setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); + } + + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user zoom individual axes + exclusively, by performing the wheel event on top of the axis. + + For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis + (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref + QCPAxisRect::setRangeZoomAxes) + + \seebaseclassmethod + + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the + axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. +*/ +void QCPAxis::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) || + !mAxisRect->rangeZoom().testFlag(orientation()) || + !mAxisRect->rangeZoomAxes(orientation()).contains(this)) + { + event->ignore(); + return; + } + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + const double delta = event->delta(); +#else + const double delta = event->angleDelta().y(); +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + const QPointF pos = event->pos(); +#else + const QPointF pos = event->position(); +#endif + + const double wheelSteps = delta/120.0; // a single step delta is +/-120 usually + const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); + scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? pos.x() : pos.y())); + mParentPlot->replot(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mNumberBeautifulPowers; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + QVector oldLabels = mTickVectorLabels; + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : nullptr, mTickLabels ? &mTickVectorLabels : nullptr); + mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels + int margin = 0; + + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + foreach (double tickPos, tickPositions) + painter->drawLine(QLineF(tickPos+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPos+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + foreach (double tickPos, tickPositions) + painter->drawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPos+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPos+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + foreach (double subTickPos, subTickPositions) + painter->drawLine(QLineF(subTickPos+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPos+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + foreach (double subTickPos, subTickPositions) + painter->drawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPos+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPos+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() +{ + int result = 0; + + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + foreach (const QString &tickLabel, tickLabels) + getMaxTickLabelSize(tickLabelFont, tickLabel, &tickLabelsSize); + result += QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width(); + result += tickLabelPadding; + } + } + + // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees): + if (!label.isEmpty()) + { + QFontMetrics fontMetrics(labelFont); + QRect bounds; + bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, label); + result += bounds.height() + labelPadding; + } + + return result; +} + +/*! \internal + + Clears the internal label cache. Upon the next \ref draw, all labels will be created new. This + method is called automatically in \ref draw, if any parameters have changed that invalidate the + cached labels, such as font, color, etc. +*/ +void QCPAxisPainterPrivate::clearCache() +{ + mLabelCache.clear(); +} + +/*! \internal + + Returns a hash that allows uniquely identifying whether the label parameters have changed such + that the cached labels must be refreshed (\ref clearCache). It is used in \ref draw. If the + return value of this method hasn't changed since the last redraw, the respective label parameters + haven't changed and cached labels may be used. +*/ +QByteArray QCPAxisPainterPrivate::generateLabelParameterHash() const +{ + QByteArray result; + result.append(QByteArray::number(mParentPlot->bufferDevicePixelRatio())); + result.append(QByteArray::number(tickLabelRotation)); + result.append(QByteArray::number(int(tickLabelSide))); + result.append(QByteArray::number(int(substituteExponent))); + result.append(QByteArray::number(int(numberMultiplyCross))); + result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); + result.append(tickLabelFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + QPointF labelAnchor; + switch (type) + { + case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; + case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; + case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; + case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; + } + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); +# else + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +# endif +#endif + } else + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(int(result.expFont.pointSize()*0.75)); + else + result.expFont.setPixelSize(int(result.expFont.pixelSize()*0.75)); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + double x = 0; + double y = 0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return {x, y}; +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +/* end of 'src/axis/axis.cpp' */ + + +/* including file 'src/scatterstyle.cpp' */ +/* modified 2021-03-29T02:30:44, size 17466 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those + are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen + is undefined, the pen of the respective plottable will be used for drawing scatters. + + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call + \ref undefinePen. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its + original size by default. To for example double the size of the path, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Copies the specified \a properties from the \a other scatter style to this scatter style. +*/ +void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) +{ + if (properties.testFlag(spPen)) + { + setPen(other.pen()); + if (!other.isPenDefined()) + undefinePen(); + } + if (properties.testFlag(spBrush)) + setBrush(other.brush()); + if (properties.testFlag(spSize)) + setSize(other.size()); + if (properties.testFlag(spShape)) + { + setShape(other.shape()); + if (other.shape() == ssPixmap) + setPixmap(other.pixmap()); + else if (other.shape() == ssCustom) + setCustomPath(other.customPath()); + } +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen + previously by calling this function and now wish to undefine the pen, call \ref undefinePen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen + implies). + + A call to \ref setPen will define a pen. +*/ +void QCPScatterStyle::undefinePen() +{ + mPenDefined = false; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + QPointF lineArray[4] = {QPointF(x-w, y), + QPointF( x, y-w), + QPointF(x+w, y), + QPointF( x, y+w)}; + painter->drawPolygon(lineArray, 4); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + QPointF lineArray[3] = {QPointF(x-w, y+0.755*w), + QPointF(x+w, y+0.755*w), + QPointF( x, y-0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssTriangleInverted: + { + QPointF lineArray[3] = {QPointF(x-w, y-0.755*w), + QPointF(x+w, y-0.755*w), + QPointF( x, y+0.977*w)}; + painter->drawPolygon(lineArray, 3); + break; + } + case ssCrossSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + break; + } + case ssPlusSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCrossCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + break; + } + case ssPlusCircle: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssPeace: + { + painter->drawEllipse(QPointF(x, y), w, w); + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + break; + } + case ssPixmap: + { + const double widthHalf = mPixmap.width()*0.5; + const double heightHalf = mPixmap.height()*0.5; +#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#else + const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#endif + if (clipRect.contains(x, y)) + painter->drawPixmap(qRound(x-widthHalf), qRound(y-heightHalf), mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} +/* end of 'src/scatterstyle.cpp' */ + + +/* including file 'src/plottable.cpp' */ +/* modified 2021-03-29T02:30:44, size 38818 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecorator +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecorator + \brief Controls how a plottable's data selection is drawn + + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref + QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. + + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the + scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref + QCPScatterStyle is itself composed of different properties such as color shape and size, the + decorator allows specifying exactly which of those properties shall be used for the selected data + point, via \ref setUsedScatterProperties. + + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref + QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance + of selected segments. + + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is + especially useful since plottables take ownership of the passed selection decorator, and thus the + same decorator instance can not be passed to multiple plottables. + + Selection decorators can also themselves perform drawing operations by reimplementing \ref + drawDecoration, which is called by the plottable's draw method. The base class \ref + QCPSelectionDecorator does not make use of this however. For example, \ref + QCPSelectionDecoratorBracket draws brackets around selected data segments. +*/ + +/*! + Creates a new QCPSelectionDecorator instance with default values +*/ +QCPSelectionDecorator::QCPSelectionDecorator() : + mPen(QColor(80, 80, 255), 2.5), + mBrush(Qt::NoBrush), + mUsedScatterProperties(QCPScatterStyle::spNone), + mPlottable(nullptr) +{ +} + +QCPSelectionDecorator::~QCPSelectionDecorator() +{ +} + +/*! + Sets the pen that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the scatter style that will be used by the parent plottable to draw scatters in selected + data segments. + + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the + plottable. The used properties can also be changed via \ref setUsedScatterProperties. +*/ +void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) +{ + mScatterStyle = scatterStyle; + setUsedScatterProperties(usedProperties); +} + +/*! + Use this method to define which properties of the scatter style (set via \ref setScatterStyle) + will be used for selected data segments. All properties of the scatter style that are not + specified in \a properties will remain as specified in the plottable's original scatter style. + + \see QCPScatterStyle::ScatterProperty +*/ +void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) +{ + mUsedScatterProperties = properties; +} + +/*! + Sets the pen of \a painter to the pen of this selection decorator. + + \see applyBrush, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyPen(QCPPainter *painter) const +{ + painter->setPen(mPen); +} + +/*! + Sets the brush of \a painter to the brush of this selection decorator. + + \see applyPen, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const +{ + painter->setBrush(mBrush); +} + +/*! + Returns the scatter style that the parent plottable shall use for selected scatter points. The + plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending + on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this + selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. + + \see applyPen, applyBrush, setScatterStyle +*/ +QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const +{ + QCPScatterStyle result(unselectedStyle); + result.setFromOther(mScatterStyle, mUsedScatterProperties); + + // if style shall inherit pen from plottable (has no own pen defined), give it the selected + // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the + // plottable: + if (!result.isPenDefined()) + result.setPen(mPen); + + return result; +} + +/*! + Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to + this selection decorator. +*/ +void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) +{ + setPen(other->pen()); + setBrush(other->brush()); + setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); +} + +/*! + This method is called by all plottables' draw methods to allow custom selection decorations to be + drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data + selection for which the decoration shall be drawn. + + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so + this method does nothing. +*/ +void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + Q_UNUSED(painter) + Q_UNUSED(selection) +} + +/*! \internal + + This method is called as soon as a selection decorator is associated with a plottable, by a call + to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access + data points via the \ref QCPAbstractPlottable::interface1D interface). + + If the selection decorator was already added to a different plottable before, this method aborts + the registration and returns false. +*/ +bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottable) + { + mPlottable = plottable; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); + return false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). Plottables that display + one-dimensional data (i.e. data points have a single key dimension and one or multiple values at + each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details + there. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line and/or scatter points \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display + two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) + data dimensions. If you want to display data with only one logical key dimension, you should + rather derive from \ref QCPAbstractPlottable1D. + + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must + implement: + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable + (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable + (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates + to pixels in either the key or value dimension. Make sure to check whether the pointer is \c nullptr before using it. If one of + the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. + When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. + Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done + by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
+*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const + + Provides access to the selection decorator of this plottable. The selection decorator controls + how selected data ranges are drawn (e.g. their pen color and fill), see \ref + QCPSelectionDecorator for details. + + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref + setSelectionDecorator. +*/ + +/*! \fn bool QCPAbstractPlottable::selected() const + + Returns true if there are any data points of the plottable currently selected. Use \ref selection + to retrieve the current \ref QCPDataSelection. +*/ + +/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const + + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on + this plottable. + + \see selected, setSelection, setSelectable +*/ + +/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() + + If this plottable is a one-dimensional plottable, i.e. it implements the \ref + QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case + of a \ref QCPColorMap) returns zero. + + You can use this method to gain read access to data coordinates while holding a pointer to the + abstract base class only. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 + + Returns the coordinate range that all data in this plottable span in the key axis dimension. For + logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref + QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only + negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points + will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref + QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could + be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 + + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span + in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref + QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign + domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and + all positive points will be ignored for range calculation. For no restriction, just set \a + inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates + whether a range could be found or not. If this is false, you shouldn't use the returned range + (e.g. no points in data). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether + there are any points selected or not. + + \see selectionChanged(const QCPDataSelection &selection) +*/ + +/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selection holds the + currently selected data ranges. + + \see selectionChanged(bool selected) +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole), + mSelectionDecorator(nullptr) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; + + mParentPlot->registerPlottable(this); + setSelectionDecorator(new QCPSelectionDecorator); +} + +QCPAbstractPlottable::~QCPAbstractPlottable() +{ + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = nullptr; + } +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + delete mSelectionDecorator; // delete old decorator if necessary + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = nullptr; + } +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + + +/*! + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \overload + + Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is + set to true, only the data points which are in the currently visible key axis range are + considered. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! \overload + + Adds this plottable to the specified \a legend. + + Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. + when the legend exists and a legend item associated with this plottable isn't already in the + legend. + + If the plottable needs a more specialized representation in the legend, you can create a + corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead + of calling this method. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + if (!legend->hasItemWithPlottable(this)) + { + legend->addItem(new QCPPlottableLegendItem(legend, this)); + return true; + } else + return false; +} + +/*! \overload + + Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). + + \see removeFromLegend +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +/*! \overload + + Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem + that is associated with this plottable is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) + return legend->removeItem(lip); + else + return false; +} + +/*! \overload + + Removes the plottable from the legend of the parent QCustomPlot. + + \see addToLegend +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return {}; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} +/* end of 'src/plottable.cpp' */ + + +/* including file 'src/item.cpp' */ +/* modified 2021-03-29T02:30:44, size 49486 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns \c nullptr if this instance is merely a QCPItemAnchor, and a valid pointer of type + QCPItemPosition* if it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.values()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(nullptr); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.values()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(nullptr); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPosition() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPosition(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return {}; + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return {}; + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes (\ref QCPItemPosition::setAxes), as fractions of + the axis rect (\ref QCPItemPosition::setAxisRect), etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned for example at a fixed pixel distance from the + top in the Y direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(nullptr), + mParentAnchorY(nullptr) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition + foreach (QCPItemPosition *child, mChildrenX.values()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(nullptr); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.values()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(nullptr); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to \c nullptr. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPosition +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPosition +*/ +QPointF QCPItemPosition::pixelPosition() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPosition, setCoords +*/ +void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) +{ + double x = pixelPosition.x(); + double y = pixelPosition.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mParentPlot->viewport().left(); + x /= double(mParentPlot->viewport().width()); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mAxisRect.data()->left(); + x /= double(mAxisRect.data()->width()); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mParentPlot->viewport().top(); + y /= double(mParentPlot->viewport().height()); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mAxisRect.data()->top(); + y /= double(mAxisRect.data()->height()); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPosition. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref + QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the + selection test becomes significantly simpler for most items. See the documentation of \ref + selectTest for what the function parameters mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + parentPlot->registerItem(this); + + QList rects = parentPlot->axisRects(); + if (!rects.isEmpty()) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns \c nullptr. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + foreach (QCPItemPosition *position, mPositions) + { + if (position->name() == name) + return position; + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return nullptr; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns \c nullptr. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + foreach (QCPItemAnchor *anchor, mAnchors) + { + if (anchor->name() == name) + return anchor; + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return nullptr; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + foreach (QCPItemAnchor *anchor, mAnchors) + { + if (anchor->name() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four + returned values. +*/ +double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + const QList lines = QList() << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + const QCPVector2D posVec(pos); + double minDistSqr = (std::numeric_limits::max)(); + foreach (const QLineF &line, lines) + { + double distSqr = posVec.distanceSquaredToLine(line.p1(), line.p2()); + if (distSqr < minDistSqr) + minDistSqr = distSqr; + } + result = qSqrt(minDistSqr); + + // filled rect, allow click inside to count as hit: + if (filledRect && result > mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return {}; +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} +/* end of 'src/item.cpp' */ + + +/* including file 'src/core.cpp' */ +/* modified 2021-03-29T02:30:44, size 127198 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const + + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used + to handle and draw selection rect interactions (see \ref setSelectionRectMode). + + \see setSelectionRect +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space + between two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space + between two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected()/setSelection() on an object or by calling \ref + deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example \ref + QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals + are emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot, afterLayout +*/ + +/*! \fn void QCustomPlot::afterLayout() + + This signal is emitted immediately after the layout step has been completed, which occurs right + before drawing the plot. This is typically during a call to \ref replot, and in such cases this + signal is emitted in between the signals \ref beforeReplot and \ref afterReplot. Unlike those + signals however, this signal is also emitted during off-screen painting, such as when calling + \ref toPixmap or \ref savePdf. + + The layout step queries all layouts and layout elements in the plot for their proposed size and + arranges the objects accordingly as preparation for the subsequent drawing step. Through this + signal, you have the opportunity to update certain things in your plot that depend crucially on + the exact dimensions/positioning of layout elements such as axes and axis rects. + + \warning However, changing any parameters of this QCustomPlot instance which would normally + affect the layouting (e.g. axis range order of magnitudes, tick label sizes, etc.) will not issue + a second run of the layout step. It will propagate directly to the draw step and may cause + graphical inconsistencies such as overlapping objects, if sizes or positions have changed. + + \see updateLayout, beforeReplot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot, afterLayout +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become \c nullptr. + + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding + axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to + the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend + is added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become \c nullptr. + + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding + axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to + the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend + is added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become \c nullptr. + + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding + axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to + the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend + is added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become \c nullptr. + + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding + axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to + the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend + is added after the main legend was removed before. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes \c nullptr. + + If an axis convenience pointer is currently \c nullptr and a new axis rect or a corresponding + axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to + the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend + is added after the main legend was removed before. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(nullptr), + yAxis(nullptr), + xAxis2(nullptr), + yAxis2(nullptr), + legend(nullptr), + mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below + mPlotLayout(nullptr), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(QCP::iNone), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(nullptr), + mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), + mMultiSelectModifier(Qt::ControlModifier), + mSelectionRectMode(QCP::srmNone), + mSelectionRect(nullptr), + mOpenGl(false), + mMouseHasMoved(false), + mMouseEventLayerable(nullptr), + mMouseSignalLayerable(nullptr), + mReplotting(false), + mReplotQueued(false), + mReplotTime(0), + mReplotTimeAverage(0), + mOpenGlMultisamples(16), + mOpenGlAntialiasedElementsBackup(QCP::aeNone), + mOpenGlCacheLabelsBackup(true) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED +# ifdef QCP_DEVICEPIXELRATIO_FLOAT + setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); +# else + setBufferDevicePixelRatio(QWidget::devicePixelRatio()); +# endif +#endif + + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + // create selection rect instance: + mSelectionRect = new QCPSelectionRect(this); + mSelectionRect->setLayer(QLatin1String("overlay")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(rpQueuedReplot); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = nullptr; + } + + mCurrentLayer = nullptr; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref + QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and + their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the + user can actually select a plottable and its data can further be restricted with the \ref + QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the + special page about the \ref dataselection "data selection mechanism". To retrieve a list of all + currently selected plottables, call \ref selectedPlottables. If you're only interested in + QCPGraphs, you may use the convenience function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple + objects (or data points) by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets how QCustomPlot processes mouse click-and-drag interactions by the user. + + If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For + example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref + QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref + selectionRect) becomes activated and allows e.g. rect zooming and data point selection. + + If you wish to provide your user both with axis range dragging and data selection/range zooming, + use this method to switch between the modes just before the interaction is processed, e.g. in + reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether + the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. + + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the + interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes + will keep the selection rect active. Upon completion of the interaction, the behaviour is as + defined by the currently set \a mode, not the mode that was set when the interaction started. + + \see setInteractions, setSelectionRect, QCPSelectionRect +*/ +void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) +{ + if (mSelectionRect) + { + if (mode == QCP::srmNone) + mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect + + // disconnect old connections: + if (mSelectionRectMode == QCP::srmSelect) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + + // establish new ones: + if (mode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } + + mSelectionRectMode = mode; +} + +/*! + Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref + QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of + the passed \a selectionRect. It can be accessed later via \ref selectionRect. + + This method is useful if you wish to replace the default QCPSelectionRect instance with an + instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. + + \see setSelectionRectMode +*/ +void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) +{ + delete mSelectionRect; + + mSelectionRect = selectionRect; + + if (mSelectionRect) + { + // establish connections with new selection rect: + if (mSelectionRectMode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } +} + +/*! + \warning This is still an experimental feature and its performance depends on the system that it + runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering + might cause context conflicts on some systems. + + This method allows to enable OpenGL plot rendering, for increased plotting performance of + graphically demanding plots (thick lines, translucent fills, etc.). + + If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, + continue plotting with hardware acceleration. The parameter \a multisampling controls how many + samples will be used per pixel, it essentially controls the antialiasing quality. If \a + multisampling is set too high for the current graphics hardware, the maximum allowed value will + be used. + + You can test whether switching to OpenGL rendering was successful by checking whether the + according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, + rendering continues with the regular software rasterizer, and an according qDebug output is + generated. + + If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint + "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override + for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a + higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the + OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is + controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching + settings are restored to what they were before OpenGL was enabled, if they weren't altered in the + meantime. + + \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL + defined. This define must be set before including the QCustomPlot header both during compilation + of the QCustomPlot library as well as when compiling your application. It is best to just include + the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. + \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c + QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a + newer OpenGL interface which is already in the "gui" module. +*/ +void QCustomPlot::setOpenGl(bool enabled, int multisampling) +{ + mOpenGlMultisamples = qMax(0, multisampling); +#ifdef QCUSTOMPLOT_USE_OPENGL + mOpenGl = enabled; + if (mOpenGl) + { + if (setupOpenGl()) + { + // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): + setAntialiasedElements(QCP::aeAll); + setPlottingHint(QCP::phCacheLabels, false); + } else + { + qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; + mOpenGl = false; + } + } else + { + // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: + if (mAntialiasedElements == QCP::aeAll) + setAntialiasedElements(mOpenGlAntialiasedElementsBackup); + if (!mPlottingHints.testFlag(QCP::phCacheLabels)) + setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); + freeOpenGl(); + } + // recreate all paint buffers: + mPaintBuffers.clear(); + setupPaintBuffers(); +#else + Q_UNUSED(enabled) + qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; +#endif +} + +/*! + Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the + viewport manually. + + The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin calculation take + the viewport to be the outer border of the plot. The viewport normally is the rect() of the + QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, or even additional axis + rects, color scales and other layout elements. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. + + Normally, this doesn't need to be set manually, because it is initialized with the regular \a + QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal + displays, 2 for High-DPI displays). + + Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called + when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and + leaves the internal buffer device pixel ratio at 1.0. +*/ +void QCustomPlot::setBufferDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBufferDevicePixelRatio = ratio; + foreach (QSharedPointer buffer, mPaintBuffers) + buffer->setDevicePixelRatio(mBufferDevicePixelRatio); + // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mBufferDevicePixelRatio = 1.0; +#endif + } +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns \c nullptr. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return nullptr; + } +} + +/*! \overload + + Returns the last plottable that was added to the plot. If there are no plottables in the plot, + returns \c nullptr. + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return nullptr; +} + +/*! + Removes the specified plottable from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). + + Returns true on success. + + \see clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes and deletes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot and deletes them. Corresponding legend items are also + removed from the default legend (QCustomPlot::legend). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns any plottable at the pixel position \a pos. Since it can capture all plottables, the + return type is the abstract base class of all plottables, QCPAbstractPlottable. + + For details, and if you wish to specify a certain plottable type (e.g. QCPGraph), see the + template method plottableAt() + + \see plottableAt(), itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const +{ + return plottableAt(pos, onlySelectable, dataIndex); +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns \c nullptr. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "mGraphs.size()" << mGraphs.size() <<"index out of bounds:" << index; + return nullptr; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns \c nullptr. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return nullptr; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or \c nullptr if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return nullptr; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return nullptr; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; +} + +/*! + Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in + the plot have a channel fill set towards the removed graph, the channel fill property of those + graphs is reset to \c nullptr (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes and deletes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot and deletes them. Corresponding legend items are also removed + from the default legend (QCustomPlot::legend). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns \c nullptr. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return nullptr; + } +} + +/*! \overload + + Returns the last item that was added to this plot. If there are no items in the plot, + returns \c nullptr. + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return nullptr; +} + +/*! + Removes the specified item from the plot and deletes it. + + Returns true on success. + + \see clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes and deletes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot and deletes them. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems() +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + removeItem(mItems[i]); + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Since it can capture all items, the + return type is the abstract base class of all items, QCPAbstractItem. + + For details, and if you wish to specify a certain item type (e.g. QCPItemLine), see the + template method itemAt() + + \see itemAt(), plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + return itemAt(pos, onlySelectable); +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see item +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, \c + nullptr is returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return nullptr; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, \c nullptr is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return nullptr; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + setupPaintBuffers(); // associates new layer with the appropriate paint buffer + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (such that relative order stays the same) + std::reverse(children.begin(), children.end()); + foreach (QCPLayerable *child, children) + child->moveToLayer(targetLayer, isFirstLayer); // prepend if isFirstLayer, otherwise append + + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + + // invalidate the paint buffer that was responsible for this layer: + if (QSharedPointer pb = layer->mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + // invalidate the paint buffers that are responsible for the layers: + if (QSharedPointer pb = layer->mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + if (QSharedPointer pb = otherLayer->mPaintBuffer.toStrongRef()) + pb->setInvalidated(); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + The order of the axis rects is given by the fill order of the \ref QCPLayout that is holding + them. For example, if the axis rects are in the top level grid layout (accessible via \ref + QCustomPlot::plotLayout), they are ordered from left to right, top to bottom, if the layout's + default \ref QCPLayoutGrid::setFillOrder "setFillOrder" of \ref QCPLayoutGrid::foColumnsFirst + "foColumnsFirst" wasn't changed. + + If you want to access axis rects by their row and column index, use the layout interface. For + example, use \ref QCPLayoutGrid::element of the top level grid layout, and \c qobject_cast the + returned layout element to \ref QCPAxisRect. (See also \ref thelayoutsystem.) + + \see axisRectCount, axisRects, QCPLayoutGrid::setFillOrder +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return nullptr; + } +} + +/*! + Returns all axis rects in the plot. + + The order of the axis rects is given by the fill order of the \ref QCPLayout that is holding + them. For example, if the axis rects are in the top level grid layout (accessible via \ref + QCustomPlot::plotLayout), they are ordered from left to right, top to bottom, if the layout's + default \ref QCPLayoutGrid::setFillOrder "setFillOrder" of \ref QCPLayoutGrid::foColumnsFirst + "foColumnsFirst" wasn't changed. + + \see axisRectCount, axisRect, QCPLayoutGrid::setFillOrder +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns \c nullptr. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores + other layout elements even if they are visually in front of the axis rect (e.g. a \ref + QCPLegend). If there is no axis rect at that position, returns \c nullptr. + + Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or + on any of its parent elements is set to false, it will not be considered. + + \see layoutElementAt +*/ +QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const +{ + QCPAxisRect *result = nullptr; + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + if (QCPAxisRect *ar = qobject_cast(currentElement)) + result = ar; + break; + } + } + } + return result; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(nullptr); + } +} + +/*! + Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is + refreshed with the new buffer contents. This is the method that must be called to make changes to + the plot, e.g. on the axis ranges or data points of graphs, visible. + + The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example + if your application calls \ref replot very quickly in succession (e.g. multiple independent + functions change some aspects of the plot and each wants to make sure the change gets replotted), + it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the + actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref + replot with this priority will only cause a single replot, avoiding redundant replots and + improving performance. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. + + If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to + replot only that specific layer via \ref QCPLayer::replot. See the documentation there for + details. + + \see replotTime +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (refreshPriority == QCustomPlot::rpQueuedReplot) + { + if (!mReplotQueued) + { + mReplotQueued = true; + QTimer::singleShot(0, this, SLOT(replot())); + } + return; + } + + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + mReplotQueued = false; + emit beforeReplot(); + +# if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + QTime replotTimer; + replotTimer.start(); +# else + QElapsedTimer replotTimer; + replotTimer.start(); +# endif + + updateLayout(); + // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: + setupPaintBuffers(); + foreach (QCPLayer *layer, mLayers) + layer->drawToPaintBuffer(); + foreach (QSharedPointer buffer, mPaintBuffers) + buffer->setInvalidated(false); + + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) + repaint(); + else + update(); + +# if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + mReplotTime = replotTimer.elapsed(); +# else + mReplotTime = replotTimer.nsecsElapsed()*1e-6; +# endif + if (!qFuzzyIsNull(mReplotTimeAverage)) + mReplotTimeAverage = mReplotTimeAverage*0.9 + mReplotTime*0.1; // exponential moving average with a time constant of 10 last replots + else + mReplotTimeAverage = mReplotTime; // no previous replots to average with, so initialize with replot time + + emit afterReplot(); + mReplotting = false; +} + +/*! + Returns the time in milliseconds that the last replot took. If \a average is set to true, an + exponential moving average over the last couple of replots is returned. + + \see replot +*/ +double QCustomPlot::replotTime(bool average) const +{ + return average ? mReplotTimeAverage : mReplotTime; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when + drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as + a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information + about cosmetic pens, see the QPainter and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it + is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(exportPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) + with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); +} + +/*! + Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the JPEG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumOuterSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + QCPPainter painter(this); + if (painter.isActive()) + { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem +#endif + if (mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + drawBackground(&painter); + foreach (QSharedPointer buffer, mPaintBuffers) + buffer->draw(&painter); + } +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect + of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + // resize and repaint the buffer: + setViewport(rect()); + replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then + determines the layerable under the cursor and forwards the event to it. Finally, emits the + specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + + // emit specialized object double click signals: + if (!candidates.isEmpty()) + { + if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) + { + int dataIndex = 0; + if (!details.first().value().isEmpty()) + dataIndex = details.first().value().dataRange().begin(); + emit plottableDoubleClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(candidates.first())) + emit axisDoubleClick(ax, details.first().value(), event); + else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(candidates.first())) + emit legendDoubleClick(lg, nullptr, event); + else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) + emit legendDoubleClick(li->parentLegend(), li, event); + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. + + If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the + selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + emit mousePress(event); + // save some state to tell in releaseEvent whether it was a click: + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) + { + if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect + mSelectionRect->startSelection(event); + } else + { + // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor: + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + if (!candidates.isEmpty()) + { + mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event) + mMouseSignalLayerableDetails = details.first(); + } + // forward event to topmost candidate which accepts the event: + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list + candidates.at(i)->mousePressEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it + in order to update the rect geometry. + + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the + layout element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + emit mouseMove(event); + + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) + mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release + + if (mSelectionRect && mSelectionRect->isActive()) + mSelectionRect->moveSelection(event); + else if (mMouseEventLayerable) // call event of affected layerable: + mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable + before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click + { + if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here + mSelectionRect->cancel(); + if (event->button() == Qt::LeftButton) + processPointSelection(event); + + // emit specialized click signals of QCustomPlot instance: + if (QCPAbstractPlottable *ap = qobject_cast(mMouseSignalLayerable)) + { + int dataIndex = 0; + if (!mMouseSignalLayerableDetails.value().isEmpty()) + dataIndex = mMouseSignalLayerableDetails.value().dataRange().begin(); + emit plottableClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(mMouseSignalLayerable)) + emit axisClick(ax, mMouseSignalLayerableDetails.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(mMouseSignalLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(mMouseSignalLayerable)) + emit legendClick(lg, nullptr, event); + else if (QCPAbstractLegendItem *li = qobject_cast(mMouseSignalLayerable)) + emit legendClick(li->parentLegend(), li, event); + mMouseSignalLayerable = nullptr; + } + + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there + { + // finish selection rect, the appropriate action will be taken via signal-slot connection: + mSelectionRect->endSelection(event); + } else + { + // call event of affected layerable: + if (mMouseEventLayerable) + { + mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); + mMouseEventLayerable = nullptr; + } + } + + if (noAntialiasingOnDrag()) + replot(rpQueuedReplot); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layerable and forwards the event to it. +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + emit mouseWheel(event); + +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + const QPointF pos = event->pos(); +#else + const QPointF pos = event->position(); +#endif + + // forward event to layerable under cursor: + foreach (QCPLayerable *candidate, layerableListAt(pos, false)) + { + event->accept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidate->wheelEvent(event); + if (event->isAccepted()) + break; + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + This function draws the entire plot, including background pixmap, with the specified \a painter. + It does not make use of the paint buffers like \ref replot, so this is the function typically + used by saving/exporting methods such as \ref savePdf or \ref toPainter. + + Note that it does not fill the background with the background brush (as the user may specify with + \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this + method. +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + updateLayout(); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + layer->draw(painter); + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement *el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref + QCPLayoutElement::update on the main plot layout. + + Here, the layout elements calculate their positions and margins, and prepare for the following + draw call. +*/ +void QCustomPlot::updateLayout() +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); + + emit afterLayout(); +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush + (\ref setBackground(const QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + +/*! \internal + + Goes through the layers and makes sure this QCustomPlot instance holds the correct number of + paint buffers and that they have the correct configuration (size, pixel ratio, etc.). + Allocations, reallocations and deletions of paint buffers are performed as necessary. It also + associates the paint buffers with the layers, so they draw themselves into the right buffer when + \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref + QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for + layers in \ref QCPLayer::lmBuffered mode. + + This method uses \ref createPaintBuffer to create new paint buffers. + + After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated + (so an attempt to replot only a single buffered layer causes a full replot). + + This method is called in every \ref replot call, prior to actually drawing the layers (into their + associated paint buffer). If the paint buffers don't need changing/reallocating, this method + basically leaves them alone and thus finishes very fast. +*/ +void QCustomPlot::setupPaintBuffers() +{ + int bufferIndex = 0; + if (mPaintBuffers.isEmpty()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) + { + QCPLayer *layer = mLayers.at(layerIndex); + if (layer->mode() == QCPLayer::lmLogical) + { + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + } else if (layer->mode() == QCPLayer::lmBuffered) + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + } + } + } + // remove unneeded buffers: + while (mPaintBuffers.size()-1 > bufferIndex) + mPaintBuffers.removeLast(); + // resize buffers to viewport size and clear contents: + foreach (QSharedPointer buffer, mPaintBuffers) + { + buffer->setSize(viewport().size()); // won't do anything if already correct size + buffer->clear(Qt::transparent); + buffer->setInvalidated(); + } +} + +/*! \internal + + This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. + + Depending on the current setting of \ref setOpenGl, and the current Qt version, different + backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper + size and device pixel ratio, and returned. +*/ +QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() +{ + if (mOpenGl) + { +#if defined(QCP_OPENGL_FBO) + return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); +#elif defined(QCP_OPENGL_PBUFFER) + return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); +#else + qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +#endif + } else + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +} + +/*! + This method returns whether any of the paint buffers held by this QCustomPlot instance are + invalidated. + + If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always + causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example + the layer order has changed, new layers were added or removed, layer modes were changed (\ref + QCPLayer::setMode), or layerables were added or removed. + + \see QCPAbstractPaintBuffer::setInvalidated +*/ +bool QCustomPlot::hasInvalidatedPaintBuffers() +{ + foreach (QSharedPointer buffer, mPaintBuffers) + { + if (buffer->invalidated()) + return true; + } + return false; +} + +/*! \internal + + When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, + surface, paint device). + + Returns true on success. + + If this method is successful, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref + QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. + + \see freeOpenGl +*/ +bool QCustomPlot::setupOpenGl() +{ +#ifdef QCP_OPENGL_FBO + freeOpenGl(); + QSurfaceFormat proposedSurfaceFormat; + proposedSurfaceFormat.setSamples(mOpenGlMultisamples); +#ifdef QCP_OPENGL_OFFSCREENSURFACE + QOffscreenSurface *surface = new QOffscreenSurface; +#else + QWindow *surface = new QWindow; + surface->setSurfaceType(QSurface::OpenGLSurface); +#endif + surface->setFormat(proposedSurfaceFormat); + surface->create(); + mGlSurface = QSharedPointer(surface); + mGlContext = QSharedPointer(new QOpenGLContext); + mGlContext->setFormat(mGlSurface->format()); + if (!mGlContext->create()) + { + qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device + { + qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); + return true; +#elif defined(QCP_OPENGL_PBUFFER) + return QGLFormat::hasOpenGL(); +#else + return false; +#endif +} + +/*! \internal + + When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the + context and frees resources). + + After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref + QCPPaintBufferPixmap) is used for subsequent replots. + + \see setupOpenGl +*/ +void QCustomPlot::freeOpenGl() +{ +#ifdef QCP_OPENGL_FBO + mGlPaintDevice.clear(); + mGlContext.clear(); + mGlSurface.clear(); +#endif +} + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = nullptr; + if (xAxis2 == axis) + xAxis2 = nullptr; + if (yAxis == axis) + yAxis = nullptr; + if (yAxis2 == axis) + yAxis2 = nullptr; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = nullptr; +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmSelect. + + First, it determines which axis rect was the origin of the selection rect judging by the starting + point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be + precise) associated with that axis rect and finds the data points that are in \a rect. It does + this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. + + Then, the actual selection is done by calling the plottables' \ref + QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details + parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a + rect receive a \ref QCPAbstractPlottable::deselectEvent. + + \see processRectZoom +*/ +void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) +{ + typedef QPair SelectionCandidate; + typedef QMultiMap SelectionCandidates; // map key is number of selected data points, so we have selections sorted by size + + bool selectionStateChanged = false; + + if (mInteractions.testFlag(QCP::iSelectPlottables)) + { + SelectionCandidates potentialSelections; + QRectF rectF(rect.normalized()); + if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) + { + // determine plottables that were hit by the rect and thus are candidates for selection: + foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) + { + if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) + { + QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); + if (!dataSel.isEmpty()) + potentialSelections.insert(dataSel.dataPointCount(), SelectionCandidate(plottable, dataSel)); + } + } + + if (!mInteractions.testFlag(QCP::iMultiSelect)) + { + // only leave plottable with most selected points in map, since we will only select a single plottable: + if (!potentialSelections.isEmpty()) + { + SelectionCandidates::iterator it = potentialSelections.begin(); + while (it != std::prev(potentialSelections.end())) // erase all except last element + it = potentialSelections.erase(it); + } + } + + bool additive = event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + // emit deselection except to those plottables who will be selected afterwards: + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + // go through selections in reverse (largest selection first) and emit select events: + SelectionCandidates::const_iterator it = potentialSelections.constEnd(); + while (it != potentialSelections.constBegin()) + { + --it; + if (mInteractions.testFlag(it.value().first->selectionCategory())) + { + bool selChanged = false; + it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } else if (mSelectionRect) + mSelectionRect->layer()->replot(); +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmZoom. + + It determines which axis rect was the origin of the selection rect judging by the starting point + of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the + provided \a rect (see \ref QCPAxisRect::zoom). + + \see processRectSelection +*/ +void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) +{ + Q_UNUSED(event) + if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) + { + QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); + affectedAxes.removeAll(static_cast(nullptr)); + axisRect->zoom(QRectF(rect), affectedAxes); + } + replot(rpQueuedReplot); // always replot to make selection rect disappear +} + +/*! \internal + + This method is called when a simple left mouse click was detected on the QCustomPlot surface. + + It first determines the layerable that was hit by the click, and then calls its \ref + QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the + multi-select modifier was pressed, see \ref setMultiSelectModifier). + + In this method the hit layerable is determined a second time using \ref layerableAt (after the + one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This + implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the + clicked layerable determined here. For example, if a non-selectable layerable is in front of a + selectable layerable at the click position, the front layerable will receive mouse events but the + selectable one in the back will receive the \ref QCPLayerable::selectEvent. + + \see processRectSelection, QCPLayerable::selectTest +*/ +void QCustomPlot::processPointSelection(QMouseEvent *event) +{ + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } +} + +/*! \internal + + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend + is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the + plottable. + + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of + \a plottable is this QCustomPlot. + + This method is called automatically in the QCPAbstractPlottable base class constructor. +*/ +bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! \internal + + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the + QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true + on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. + + This graph specific registration happens in addition to the call to \ref registerPlottable by the + QCPAbstractPlottable base class. +*/ +bool QCustomPlot::registerGraph(QCPGraph *graph) +{ + if (!graph) + { + qDebug() << Q_FUNC_INFO << "passed graph is zero"; + return false; + } + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; + return false; + } + + mGraphs.append(graph); + return true; +} + + +/*! \internal + + Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + This method is called automatically in the QCPAbstractItem base class constructor. +*/ +bool QCustomPlot::registerItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); + return false; + } + if (item->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } + + mItems.append(item); + if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) + item->setLayer(currentLayer()); + return true; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, + only those layerables that are selectable will be considered. (Layerable subclasses communicate + their selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableListAt, layoutElementAt, axisRectAt +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + QList details; + QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : nullptr); + if (selectionDetails && !details.isEmpty()) + *selectionDetails = details.first(); + if (!candidates.isEmpty()) + return candidates.first(); + else + return nullptr; +} + +/*! \internal + + Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + The returned list is sorted by the layerable/drawing order such that the layerable that appears + on top in the plot is at index 0 of the returned list. If you only need to know the top + layerable, rather use \ref layerableAt. + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableAt, layoutElementAt, axisRectAt +*/ +QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const +{ + QList result; + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : nullptr); + if (dist >= 0 && dist < selectionTolerance()) + { + result.append(layerables.at(i)); + if (selectionDetails) + selectionDetails->append(details); + } + } + } + return result; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The \a resolution will be written to the image file header (if the file format supports this) and + has no direct consequence for the quality or the pixel size. However, if opening the image with a + tool which respects the metadata, it will be able to scale the image to match either a given size + in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in + which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted + to the format's expected resolution unit internally. + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + QImage buffer = toPixmap(width, height, scale).toImage(); + + int dotsPerMeter = 0; + switch (resolutionUnit) + { + case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; + case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; + case QCP::ruDotsPerInch: dotsPerMeter = int(resolution/0.0254); break; + } + buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} +/* end of 'src/core.cpp' */ + + +/* including file 'src/colorgradient.cpp' */ +/* modified 2021-03-29T02:30:44, size 25278 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + Apart from red, green and blue components, the gradient also interpolates the alpha values of the + configured color stops. This allows to display some portions of the data range as transparent in + the plot. + + How NaN values are interpreted can be configured with \ref setNanHandling. + + \image html QCPColorGradient.png + + The constructor \ref QCPColorGradient(GradientPreset preset) allows directly converting a \ref + GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset + to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color + stops with \ref setColorStopAt. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient() : + mLevelCount(350), + mColorInterpolation(ciRGB), + mNanHandling(nhNone), + mNanColor(Qt::black), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); +} + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mNanHandling(nhNone), + mNanColor(Qt::black), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mNanHandling == this ->mNanHandling) && + (other.mNanColor == this->mNanColor) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. The minimum number of levels is 2. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with + \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets how NaNs in the data are displayed in the plot. + + \see setNanColor +*/ +void QCPColorGradient::setNanHandling(QCPColorGradient::NanHandling handling) +{ + mNanHandling = handling; +} + +/*! + Sets the color that NaN data is represented by, if \ref setNanHandling is set + to ref nhNanColor. + + \see setNanHandling +*/ +void QCPColorGradient::setNanColor(const QColor &color) +{ + mNanColor = color; +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! \overload + + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. + + Use the overloaded method to additionally provide alpha map data. + + The QRgb values that are placed in \a scanLine have their r, g, and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + const bool skipNanCheck = mNanHandling == nhNone; + const double posToIndexFactor = !logarithmic ? (mLevelCount-1)/range.size() : (mLevelCount-1)/qLn(range.upper/range.lower); + for (int i=0; i::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Returns true if the color gradient uses transparency, i.e. if any of the configured color stops + has an alpha value below 255. +*/ +bool QCPColorGradient::stopsUseAlpha() const +{ + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + { + if (it.value().alpha() < 255) + return true; + } + return false; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/double(mLevelCount-1); + const bool useAlpha = stopsUseAlpha(); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + if (useAlpha) + { + const QColor col = std::prev(it).value(); + const double alphaPremultiplier = col.alpha()/255.0; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(int(col.red()*alphaPremultiplier), + int(col.green()*alphaPremultiplier), + int(col.blue()*alphaPremultiplier), + col.alpha()); + } else + mColorBuffer[i] = std::prev(it).value().rgba(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + if (useAlpha) + { + const QColor &col = it.value(); + const double alphaPremultiplier = col.alpha()/255.0; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(int(col.red()*alphaPremultiplier), + int(col.green()*alphaPremultiplier), + int(col.blue()*alphaPremultiplier), + col.alpha()); + } else + mColorBuffer[i] = it.value().rgba(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = std::prev(it); + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + if (useAlpha) + { + const int alpha = int((1-t)*low.value().alpha() + t*high.value().alpha()); + const double alphaPremultiplier = alpha/255.0; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(int( ((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier ), + int( ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier ), + int( ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier ), + alpha); + } else + { + mColorBuffer[i] = qRgb(int( ((1-t)*low.value().red() + t*high.value().red()) ), + int( ((1-t)*low.value().green() + t*high.value().green()) ), + int( ((1-t)*low.value().blue() + t*high.value().blue())) ); + } + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + if (useAlpha) + { + const QRgb rgb = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + const double alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); + mColorBuffer[i] = qRgba(int(qRed(rgb)*alpha), int(qGreen(rgb)*alpha), int(qBlue(rgb)*alpha), int(255*alpha)); + } + else + { + mColorBuffer[i] = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + } + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + const QRgb rgb = mColorStops.constBegin().value().rgb(); + const double alpha = mColorStops.constBegin().value().alphaF(); + mColorBuffer.fill(qRgba(int(qRed(rgb)*alpha), int(qGreen(rgb)*alpha), int(qBlue(rgb)*alpha), int(255*alpha))); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} +/* end of 'src/colorgradient.cpp' */ + + +/* including file 'src/selectiondecorator-bracket.cpp' */ +/* modified 2021-03-29T02:30:44, size 12308 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecoratorBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecoratorBracket + \brief A selection decorator which draws brackets around each selected data segment + + Additionally to the regular highlighting of selected segments via color, fill and scatter style, + this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data + segment of the plottable. + + The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and + \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref + setBracketBrush. + + To introduce custom bracket styles, it is only necessary to sublcass \ref + QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the + base class. +*/ + +/*! + Creates a new QCPSelectionDecoratorBracket instance with default values. +*/ +QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : + mBracketPen(QPen(Qt::black)), + mBracketBrush(Qt::NoBrush), + mBracketWidth(5), + mBracketHeight(50), + mBracketStyle(bsSquareBracket), + mTangentToData(false), + mTangentAverage(2) +{ + +} + +QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() +{ +} + +/*! + Sets the pen that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) +{ + mBracketPen = pen; +} + +/*! + Sets the brush that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) +{ + mBracketBrush = brush; +} + +/*! + Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of + the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketWidth(int width) +{ + mBracketWidth = width; +} + +/*! + Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis + of the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketHeight(int height) +{ + mBracketHeight = height; +} + +/*! + Sets the shape that the bracket/marker will have. + + \see setBracketWidth, setBracketHeight +*/ +void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) +{ + mBracketStyle = style; +} + +/*! + Sets whether the brackets will be rotated such that they align with the slope of the data at the + position that they appear in. + + For noisy data, it might be more visually appealing to average the slope over multiple data + points. This can be configured via \ref setTangentAverage. +*/ +void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) +{ + mTangentToData = enabled; +} + +/*! + Controls over how many data points the slope shall be averaged, when brackets shall be aligned + with the data (if \ref setTangentToData is true). + + From the position of the bracket, \a pointCount points towards the selected data range will be + taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to + disabling \ref setTangentToData. +*/ +void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) +{ + mTangentAverage = pointCount; + if (mTangentAverage < 1) + mTangentAverage = 1; +} + +/*! + Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and + indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening + bracket, respectively). + + The passed \a painter already contains all transformations that are necessary to position and + rotate the bracket appropriately. Painting operations can be performed as if drawing upright + brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. + + If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket + shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should + reimplement. +*/ +void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const +{ + switch (mBracketStyle) + { + case bsSquareBracket: + { + painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); + painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + break; + } + case bsHalfEllipse: + { + painter->drawArc(QRectF(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight), -90*16, -180*16*direction); + break; + } + case bsEllipse: + { + painter->drawEllipse(QRectF(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight)); + break; + } + case bsPlus: + { + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); + break; + } + default: + { + qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); + break; + } + } +} + +/*! + Draws the bracket decoration on the data points at the begin and end of each selected data + segment given in \a seletion. + + It uses the method \ref drawBracket to actually draw the shapes. + + \seebaseclassmethod +*/ +void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + if (!mPlottable || selection.isEmpty()) return; + + if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) + { + foreach (const QCPDataRange &dataRange, selection.dataRanges()) + { + // determine position and (if tangent mode is enabled) angle of brackets: + int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; + int closeBracketDir = -openBracketDir; + QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); + QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); + double openBracketAngle = 0; + double closeBracketAngle = 0; + if (mTangentToData) + { + openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); + closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); + } + // draw opening bracket: + QTransform oldTransform = painter->transform(); + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(openBracketPos); + painter->rotate(openBracketAngle/M_PI*180.0); + drawBracket(painter, openBracketDir); + painter->setTransform(oldTransform); + // draw closing bracket: + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(closeBracketPos); + painter->rotate(closeBracketAngle/M_PI*180.0); + drawBracket(painter, closeBracketDir); + painter->setTransform(oldTransform); + } + } +} + +/*! \internal + + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. + This method returns the angle in radians by which a bracket at the given \a dataIndex must be + rotated. + + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening + or closing bracket. Since for slope calculation multiple data points are required, this defines + the direction in which the algorithm walks, starting at \a dataIndex, to average those data + points. (see \ref setTangentToData and \ref setTangentAverage) + + \a interface1d is the interface to the plottable's data which is used to query data coordinates. +*/ +double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const +{ + if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) + return 0; + direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 + + // how many steps we can actually go from index in the given direction without exceeding data bounds: + int averageCount; + if (direction < 0) + averageCount = qMin(mTangentAverage, dataIndex); + else + averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); + qDebug() << averageCount; + // calculate point average of averageCount points: + QVector points(averageCount); + QPointF pointsAverage; + int currentIndex = dataIndex; + for (int i=0; ikeyAxis(); + QCPAxis *valueAxis = mPlottable->valueAxis(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {0, 0}; } + + if (keyAxis->orientation() == Qt::Horizontal) + return {keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))}; + else + return {valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))}; +} +/* end of 'src/selectiondecorator-bracket.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.cpp' */ +/* modified 2021-03-29T02:30:44, size 47193 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = nullptr; + + foreach (QCPAxis *axis, axes()) + removeAxis(axis); +} + +/*! + Returns the number of axes on the axis rect side specified with \a type. + + \see axis +*/ +int QCPAxisRect::axisCount(QCPAxis::AxisType type) const +{ + return mAxes.value(type).size(); +} + +/*! + Returns the axis with the given \a index on the axis rect side specified with \a type. + + \see axisCount, axes +*/ +QCPAxis *QCPAxisRect::axis(QCPAxis::AxisType type, int index) const +{ + QList ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return nullptr; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns \c nullptr. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return nullptr; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return nullptr; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return nullptr; + } + } + if (!mAxes[type].isEmpty()) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + + // reset convenience axis pointers on parent QCustomPlot if they are unset: + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + switch (type) + { + case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } + case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } + case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } + case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } + } + } + + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists) + it.value()[1]->setOffset(axis->offset()); + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom + specific axes, use the overloaded version of this method. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect) +{ + zoom(pixelRect, axes()); +} + +/*! \overload + + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) +{ + foreach (QCPAxis *axis, affectedAxes) + { + if (!axis) + { + qDebug() << Q_FUNC_INFO << "a passed axis was zero"; + continue; + } + QCPRange pixelRange; + if (axis->orientation() == Qt::Horizontal) + pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); + else + pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); + axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); + } +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li tick visibility (\ref QCPAxis::setTicks) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick count of ticker (\ref QCPAxisTicker::setTickCount) + \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) + + Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); + xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); + yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + foreach (QCPAbstractPlottable *plottable, mParentPlot->mPlottables) + { + if (plottable->keyAxis()->axisRect() == this || plottable->valueAxis()->axisRect() == this) + result.append(plottable); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + foreach (QCPGraph *graph, mParentPlot->mGraphs) + { + if (graph->keyAxis()->axisRect() == this || graph->valueAxis()->axisRect() == this) + result.append(graph); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + foreach (QCPAbstractItem *item, mParentPlot->mItems) + { + if (item->clipAxisRect() == this) + { + result.append(item); + continue; + } + foreach (QCPItemPosition *position, item->positions()) + { + if (position->axisRect() == this || + position->keyAxis()->axisRect() == this || + position->valueAxis()->axisRect() == this) + { + result.append(item); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + foreach (QCPAxis *axis, axes()) + axis->setupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeDragAxes to retrieve a list with all set axes). + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeDragHorzAxis.isEmpty() ? nullptr : mRangeDragHorzAxis.first().data(); + else + return mRangeDragVertAxis.isEmpty() ? nullptr : mRangeDragVertAxis.first().data(); +} + +/*! + Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeZoomHorzAxis.isEmpty() ? nullptr : mRangeZoomHorzAxis.first().data(); + else + return mRangeZoomVertAxis.isEmpty() ? nullptr : mRangeZoomVertAxis.first().data(); +} + +/*! + Returns all range drag axes of the \a orientation provided. + + \see rangeZoomAxis, setRangeZoomAxes +*/ +QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + foreach (QPointer axis, mRangeDragHorzAxis) + { + if (!axis.isNull()) + result.append(axis.data()); + } + } else + { + foreach (QPointer axis, mRangeDragVertAxis) + { + if (!axis.isNull()) + result.append(axis.data()); + } + } + return result; +} + +/*! + Returns all range zoom axes of the \a orientation provided. + + \see rangeDragAxis, setRangeDragAxes +*/ +QList QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + foreach (QPointer axis, mRangeZoomHorzAxis) + { + if (!axis.isNull()) + result.append(axis.data()); + } + } else + { + foreach (QPointer axis, mRangeZoomVertAxis) + { + if (!axis.isNull()) + result.append(axis.data()); + } + } + return result; +} + +/*! + Returns the range zoom factor of the \a orientation provided. + + \see setRangeZoomFactor +*/ +double QCPAxisRect::rangeZoomFactor(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeZoomFactorHorz : mRangeZoomFactorVert); +} + +/*! + Sets which axis orientation may be range dragged by the user with mouse interaction. + What orientation corresponds to which specific axis can be set with + \ref setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical). By + default, the horizontal axis is the bottom axis (xAxis) and the vertical axis + is the left axis (yAxis). + + To disable range dragging entirely, pass \c nullptr as \a orientations or remove \ref + QCP::iRangeDrag from \ref QCustomPlot::setInteractions. To enable range dragging for both + directions, pass Qt::Horizontal | Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass \c nullptr as \a orientations or remove \ref + QCP::iRangeZoom from \ref QCustomPlot::setInteractions. To enable range zooming for both + directions, pass Qt::Horizontal | Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! \overload + + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on + the QCustomPlot widget. Pass \c nullptr if no axis shall be dragged in the respective + orientation. + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to dragging interactions. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag + orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag + motion, use the overload taking two separate lists for horizontal and vertical dragging. +*/ +void QCPAxisRect::setRangeDragAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical dragging, and + define specifically which axis reacts to which drag orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) +{ + mRangeDragHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeDragVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on + the QCustomPlot widget. Pass \c nullptr if no axis shall be zoomed in the respective orientation. + + The two axes can be zoomed with different strengths, when different factors are passed to \ref + setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to zooming interactions. + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical range zooming. The + zoom orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom + interaction, use the overload taking two separate lists for horizontal and vertical zooming. +*/ +void QCPAxisRect::setRangeZoomAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical zooming, and + define specifically which axis reacts to which zoom orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) +{ + mRangeZoomHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeZoomVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (!axesList.isEmpty()) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Reacts to a change in layout to potentially set the convenience axis pointers \ref + QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective + axes of this axis rect. This is only done if the respective convenience pointer is currently zero + and if there is no QCPAxisRect at position (0, 0) of the plot layout. + + This automation makes it simpler to replace the main axis rect with a newly created one, without + the need to manually reset the convenience pointers. +*/ +void QCPAxisRect::layoutChanged() +{ + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) + mParentPlot->xAxis = axis(QCPAxis::atBottom); + if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) + mParentPlot->yAxis = axis(QCPAxis::atLeft); + if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) + mParentPlot->xAxis2 = axis(QCPAxis::atTop); + if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) + mParentPlot->yAxis2 = axis(QCPAxis::atRight); + } +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragStartHorzRange.clear(); + foreach (QPointer axis, mRangeDragHorzAxis) + mDragStartHorzRange.append(axis.isNull() ? QCPRange() : axis->range()); + mDragStartVertRange.clear(); + foreach (QPointer axis, mRangeDragVertAxis) + mDragStartVertRange.append(axis.isNull() ? QCPRange() : axis->range()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + for (int i=0; i= mDragStartHorzRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag.testFlag(Qt::Vertical)) + { + for (int i=0; i= mDragStartVertRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } + + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->angleDelta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the delta may then be multiples + of 120. This is taken into account here, by calculating \a wheelSteps and using it as exponent of + the range zoom factor. This takes care of the wheel direction automatically, by inverting the + factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + const double delta = event->delta(); +#else + const double delta = event->angleDelta().y(); +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + const QPointF pos = event->pos(); +#else + const QPointF pos = event->position(); +#endif + + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = delta/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + foreach (QPointer axis, mRangeZoomHorzAxis) + { + if (!axis.isNull()) + axis->scaleRange(factor, axis->pixelToCoord(pos.x())); + } + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + foreach (QPointer axis, mRangeZoomVertAxis) + { + if (!axis.isNull()) + axis->scaleRange(factor, axis->pixelToCoord(pos.y())); + } + } + mParentPlot->replot(); + } + } +} +/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-legend.cpp' */ +/* modified 2021-03-29T02:30:44, size 31762 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(0, 0, 0, 0)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ + setAntialiased(false); +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumOuterSizeHint and \ref + maximumOuterSizeHint of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSize iconSize = mParentLegend->iconSize(); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + QRect iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->name()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. + + \seebaseclassmethod +*/ +QSize QCPPlottableLegendItem::minimumOuterSizeHint() const +{ + if (!mPlottable) return {}; + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the + plottable, for which a legend item shall be created. In the case of the main legend (\ref + QCustomPlot::legend), simply adding plottables to the plot while \ref + QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding + legend items. The legend item associated with a certain plottable can be removed with \ref + QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and + manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref + addItem, \ref removeItem, etc. + + Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref + QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement + "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds + an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as + mentioned above. In principle, any other layout elements may also be added to a legend via the + normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout + System\endlink for examples on how to add other elements to the legend and move it outside the axis + rect. + + Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control + in which order (column first or row first) the legend is filled up when calling \ref addItem, and + at which column or row wrapping occurs. The default fill order for legends is \ref foRowsFirst. + + By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the + inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement + interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as \ref + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() : + mIconTextPadding{} +{ + setFillOrder(QCPLayoutGrid::foRowsFirst); + setWrap(0); + + setRowSpacing(3); + setColumnSpacing(8); + setMargins(QMargins(7, 5, 7, 4)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black, 0)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. If non-legend items were added to the legend, and the element + at the specified cell index is not a QCPAbstractLegendItem, returns \c nullptr. + + Note that the linear index depends on the current fill order (\ref setFillOrder). + + \see itemCount, addItem, itemWithPlottable +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns \c nullptr. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return nullptr; +} + +/*! + Returns the number of items currently in the legend. It is identical to the base class + QCPLayoutGrid::elementCount(), and unlike the other "item" interface methods of QCPLegend, + doesn't only address elements which can be cast to QCPAbstractLegendItem. + + Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid + base class which allows creating empty cells), they are included in the returned count. + + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a item. + + \see hasItemWithPlottable +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. The element is arranged according to the + current fill order (\ref setFillOrder) and wrapping (\ref setWrap). + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. + + \see removeItem, item, hasItem +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + return addElement(item); +} + +/*! \overload + + Removes the item with the specified \a index from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes + elements derived from \ref QCPAbstractLegendItem. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (item(i)) + removeAt(i); // don't use removeItem() because it would unnecessarily reorder the whole legend for each item + } + setFillOrder(fillOrder(), true); // get rid of empty cells by reordering once after all items are removed +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + if (parentPlot && !parentPlot->legend) + parentPlot->legend = this; +} +/* end of 'src/layoutelements/layoutelement-legend.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.cpp' */ +/* modified 2021-03-29T02:30:44, size 12925 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPTextElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPTextElement + \brief A layout element displaying a text + + The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, + \ref setTextColor, and \ref setTextFlags. + + A text element can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation +*/ + +/* start documentation of signals */ + +/*! \fn void QCPTextElement::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/*! \fn void QCPTextElement::clicked(QMouseEvent *event) + + This signal is emitted when the text element is clicked. + + \see doubleClicked, selectTest +*/ + +/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) + + This signal is emitted when the text element is double clicked. + + \see clicked, selectTest +*/ + +/* end documentation of signals */ + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref + setText). +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mText(), + mTextFlags(Qt::AlignCenter), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter), + mFont(QFont(QLatin1String("sans serif"), int(pointSize))), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), int(pointSize))), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + mFont.setPointSizeF(pointSize); // set here again as floating point, because constructor above only takes integer + if (parentPlot) + { + mFont = parentPlot->font(); + mFont.setPointSizeF(pointSize); + mSelectedFont = parentPlot->font(); + mSelectedFont.setPointSizeF(pointSize); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize and the specified \a fontFamily. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter), + mFont(QFont(fontFamily, int(pointSize))), + mTextColor(Qt::black), + mSelectedFont(QFont(fontFamily, int(pointSize))), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + mFont.setPointSizeF(pointSize); // set here again as floating point, because constructor above only takes integer + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with the specified \a font. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter), + mFont(font), + mTextColor(Qt::black), + mSelectedFont(font), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor, setTextFlags +*/ +void QCPTextElement::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of + \c Qt::AlignmentFlag and \c Qt::TextFlag enums. + + Possible enums are: + - Qt::AlignLeft + - Qt::AlignRight + - Qt::AlignHCenter + - Qt::AlignJustify + - Qt::AlignTop + - Qt::AlignBottom + - Qt::AlignVCenter + - Qt::AlignCenter + - Qt::TextDontClip + - Qt::TextSingleLine + - Qt::TextExpandTabs + - Qt::TextShowMnemonic + - Qt::TextWordWrap + - Qt::TextIncludeTrailingSpaces +*/ +void QCPTextElement::setTextFlags(int flags) +{ + mTextFlags = flags; +} + +/*! + Sets the \a font of the text. + + \see setTextColor, setSelectedFont +*/ +void QCPTextElement::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the text. + + \see setFont, setSelectedTextColor +*/ +void QCPTextElement::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). + + \see setFont +*/ +void QCPTextElement::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPTextElement::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this text element. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPTextElement::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this text element to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPTextElement::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/* inherits documentation from base class */ +void QCPTextElement::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, mTextFlags, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPTextElement::minimumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, mText).size()); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPTextElement::maximumOuterSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result(metrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, mText).size()); + result.setWidth(QWIDGETSIZE_MAX); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPTextElement::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/*! + Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is + within the bounding box of the text element's text. Note that this bounding box is updated in the + draw call. + + If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text + element is not selectable (\ref setSelectable), returns -1. + + \seebaseclassmethod +*/ +double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! + Accepts the mouse event in order to emit the according click signal in the \ref + mouseReleaseEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->accept(); +} + +/*! + Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref + mousePressEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) + emit clicked(event); +} + +/*! + Emits the \ref doubleClicked signal. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + emit doubleClicked(event); +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPTextElement::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPTextElement::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} +/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.cpp' */ +/* modified 2021-03-29T02:30:44, size 26531 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mGradient(QCPColorGradient::gpCold), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, label and ticker (the latter will be shared and not copied). +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + QString labelTransfer; + QSharedPointer tickerTransfer; + // transfer/revert some settings on old axis if it exists: + bool doTransfer = !mColorAxis.isNull(); + if (doTransfer) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + tickerTransfer = mColorAxis.data()->ticker(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + const QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + if (doTransfer) + { + mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setTicker(tickerTransfer); + } + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are associated with colors linearly + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + Note that this method controls the coordinate transformation. For logarithmic scales, you will + likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting + the color scale's \ref axis ticker to an instance of \ref QCPAxisTickerLog : + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-colorscale + + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick + creation. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + { + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + } else + { +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + mAxisRect.data()->setRangeDrag(nullptr); +#else + mAxisRect.data()->setRangeDrag({}); +#endif + } +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + { + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + } else + { +#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0) + mAxisRect.data()->setRangeDrag(nullptr); +#else + mAxisRect.data()->setRangeZoom({}); +#endif + } +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + QCP::SignDomain sign = QCP::sdBoth; + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + foreach (QCPColorMap *map, maps) + { + if (!map->realVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (map->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = map->data()->dataBounds(); + if (sign == QCP::sdPositive) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == QCP::sdNegative) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event, details); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + const QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. + + \seebaseclassmethod +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, format); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + const QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} +/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ + + +/* including file 'src/plottables/plottable-graph.cpp' */ +/* modified 2021-03-29T02:30:44, size 74518 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraphData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraphData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPGraphDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPGraphData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPGraphData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and value set to zero. +*/ +QCPGraphData::QCPGraphData() : + key(0), + value(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. +*/ +QCPGraphData::QCPGraphData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPGraphDataContainer. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpgraph-appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPGraph::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually + but use QCustomPlot::removePlottable() instead. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mLineStyle{}, + mScatterSkip{}, + mAdaptiveSampling{} +{ + // special handling for QCPGraphs to maintain the simple graph interface: + mParentPlot->registerGraph(this); + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterSkip(0); + setChannelFillGraph(nullptr); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 + + \see addData +*/ +void QCPGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPGraph::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = nullptr; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = nullptr; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(double key, double value) +{ + mDataContainer->add(QCPGraphData(key, value)); +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = int(closestDataPoint-mDataContainer->constBegin()); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + // draw line: + if (mLineStyle != lsNone) + { + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lines); + else + drawLinePlot(painter, lines); // also step plots can be drawn as a line plot + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, and branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange) const +{ + if (!lines) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing) + std::reverse(lineData.begin(), lineData.end()); + + switch (mLineStyle) + { + case lsNone: lines->clear(); break; + case lsLine: *lines = dataToLines(lineData); break; + case lsStepLeft: *lines = dataToStepLeftLines(lineData); break; + case lsStepRight: *lines = dataToStepRightLines(lineData); break; + case lsStepCenter: *lines = dataToStepCenterLines(lineData); break; + case lsImpulse: *lines = dataToImpulseLines(lineData); break; + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then + converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be + passed to \ref drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. +*/ +void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + if (!scatters) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } + + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + + if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing) + std::reverse(data.begin(), data.end()); + + scatters->resize(data.size()); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } + } else + { + for (int i=0; icoordToPixel(data.at(i).key)); + (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + result[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key)); + result[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepLeft. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepLeftLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(lastValue); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(key); + result[i*2+1].setY(lastValue); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepRight. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepRightLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(value); + result[i*2+0].setY(lastKey); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(value); + result[i*2+1].setY(lastKey); + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(lastKey); + result[i*2+0].setY(value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(lastKey); + result[i*2+1].setY(value); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepCenter. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepCenterLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastValue); + result[0].setY(lastKey); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(lastValue); + result[i*2-1].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + } + result[data.size()*2-1].setX(lastValue); + result[data.size()*2-1].setY(lastKey); + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastKey); + result[0].setY(lastValue); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(key); + result[i*2-1].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + } + result[data.size()*2-1].setX(lastKey); + result[data.size()*2-1].setY(lastValue); + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsImpulse. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot +*/ +QVector QCPGraph::dataToImpulseLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(valueAxis->coordToPixel(0)); + result[i*2+0].setY(key); + result[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(valueAxis->coordToPixel(0)); + result[i*2+1].setX(key); + result[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref + getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. + + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), + this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to + operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN + segments of the two involved graphs, before passing the overlapping pairs to \ref + getChannelFillPolygon. + + Pass the points of this graph's line as \a lines, in pixel coordinates. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + const QVector segments = getNonNanSegments(lines, keyAxis()->orientation()); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + foreach (QCPDataRange segment, segments) + painter->drawPolygon(getFillPolygon(lines, segment)); + } else + { + // draw fill between this graph and mChannelFillGraph: + QVector otherLines; + mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount())); + if (!otherLines.isEmpty()) + { + QVector otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); + QVector > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines); + for (int i=0; idrawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second)); + } + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + foreach (const QPointF &scatter, scatters) + style.drawShape(painter, scatter.x(), scatter.y()); +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, drawImpulsePlot, QCPAbstractPlottable1D::drawPolyline +*/ +void QCPGraph::drawLinePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in + pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines + from the regular graph data points. + + \see drawLinePlot, drawScatterPlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen oldPen = painter->pen(); + QPen newPen = painter->pen(); + newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(newPen); + painter->drawLines(lines); + painter->setPen(oldPen); + } +} + +/*! \internal + + Returns via \a lineData the data points that need to be visualized for this graph when plotting + graph lines, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getLines to retrieve the basic working set of data. + + \see getOptimizedScatterData +*/ +void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + if (!lineData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (begin == end) return; + + int dataCount = int(end-begin); + int maxCount = (std::numeric_limits::max)(); + if (mAdaptiveSampling) + { + double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + if (2*keyPixelSpan+2 < static_cast((std::numeric_limits::max)())) + maxCount = int(2*keyPixelSpan+2); + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + QCPGraphDataContainer::const_iterator it = begin; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(begin->key)+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it->value < minValue) + minValue = it->value; + else if (it->value > maxValue) + maxValue = it->value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + lastIntervalEndKey = (it-1)->key; + minValue = it->value; + maxValue = it->value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + lineData->resize(dataCount); + std::copy(begin, end, lineData->begin()); + } +} + +/*! \internal + + Returns via \a scatterData the data points that need to be visualized for this graph when + plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getScatters to retrieve the basic working set of data. + + \see getOptimizedLineData +*/ +void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + if (!scatterData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int beginIndex = int(begin-mDataContainer->constBegin()); + int endIndex = int(end-mDataContainer->constBegin()); + while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++beginIndex; + ++begin; + } + if (begin == end) return; + int dataCount = int(end-begin); + int maxCount = (std::numeric_limits::max)(); + if (mAdaptiveSampling) + { + int keyPixelSpan = int(qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key))); + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = int(beginIndex); + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator minValueIt = it; + QCPGraphDataContainer::const_iterator maxValueIt = it; + QCPGraphDataContainer::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(begin->key)+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + // main loop over data points: + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) + { + minValue = it->value; + minValueIt = it; + } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) + { + maxValue = it->value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else + intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + minValue = it->value; + maxValue = it->value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int intervalItIndex = int(intervalIt-mDataContainer->constBegin()); + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: + { + intervalItIndex += scatterModulo; + if (intervalItIndex < itIndex) + intervalIt += scatterModulo; + else + { + intervalIt = it; + intervalItIndex = itIndex; + } + } + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + scatterData->reserve(dataCount); + while (it != end) + { + scatterData->append(*it); + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + This method takes into account that the drawing of data lines at the axis rect border always + requires the points just outside the visible axis range. So \a begin and \a end may actually + indicate a range that contains one additional data point to the left and right of the visible + axis range. +*/ +void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + This method goes through the passed points in \a lineData and returns a list of the segments + which don't contain NaN data points. + + \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check + for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c + Qt::Vertical, the \a x member is checked. + + \see getOverlappingSegments, drawFill +*/ +QVector QCPGraph::getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const +{ + QVector result; + const int n = lineData->size(); + + QCPDataRange currentSegment(-1, -1); + int i = 0; + + if (keyOrientation == Qt::Horizontal) + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } else // keyOrientation == Qt::Vertical + { + while (i < n) + { + while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point + ++i; + if (i == n) + break; + currentSegment.setBegin(i++); + while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data + ++i; + currentSegment.setEnd(i++); + result.append(currentSegment); + } + } + return result; +} + +/*! \internal + + This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and + \a otherSegments, and their associated point data \a thisData and \a otherData. + + It returns all pairs of segments (the first from \a thisSegments, the second from \a + otherSegments), which overlap in plot coordinates. + + This method is useful in the case of a channel fill between two graphs, when only those non-NaN + segments which actually overlap in their key coordinate shall be considered for drawing a channel + fill polygon. + + It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and + that the segments don't overlap themselves. The same is assumed for the segments in \a + otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. + + \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon +*/ +QVector > QCPGraph::getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const +{ + QVector > result; + if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty()) + return result; + + int thisIndex = 0; + int otherIndex = 0; + const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; + while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) + { + if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++thisIndex; + continue; + } + if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow + { + ++otherIndex; + continue; + } + double thisLower, thisUpper, otherLower, otherUpper; + if (!verticalKey) + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).x(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).x(); + } else + { + thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); + thisUpper = thisData->at(thisSegments.at(thisIndex).end()-1).y(); + otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); + otherUpper = otherData->at(otherSegments.at(otherIndex).end()-1).y(); + } + + int bPrecedence; + if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) + result.append(QPair(thisSegments.at(thisIndex), otherSegments.at(otherIndex))); + + if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment + ++otherIndex; + else // otherSegment reaches further than thisSegment, so continue with next thisSegment, keeping current otherSegment + ++thisIndex; + } + + return result; +} + +/*! \internal + + Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) + have overlap. + + The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the + \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher + coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if + both segment's upper bounds are identical, 0 is returned as \a bPrecedence. + + It is assumed that the lower bounds always have smaller or equal values than the upper bounds. + + \see getOverlappingSegments +*/ +bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const +{ + bPrecedence = 0; + if (aLower > bUpper) + { + bPrecedence = -1; + return false; + } else if (bLower > aUpper) + { + bPrecedence = 1; + return false; + } else + { + if (aUpper > bUpper) + bPrecedence = -1; + else if (aUpper < bUpper) + bPrecedence = 1; + + return true; + } +} + +/*! \internal + + Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. + The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates + is in positive or negative infinity. So this case is handled separately by just closing the fill + polygon on the axis which lies in the direction towards the zero value. + + \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether + the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or + y value of the returned point, respectively. +*/ +QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } + + QPointF result; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->orientation() == Qt::Horizontal) + { + result.setX(matchingDataPoint.x()); + result.setY(valueAxis->coordToPixel(0)); + } else // keyAxis->orientation() == Qt::Vertical + { + result.setX(valueAxis->coordToPixel(0)); + result.setY(matchingDataPoint.y()); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setX(keyAxis->axisRect()->right()); + else + result.setX(keyAxis->axisRect()->left()); + result.setY(matchingDataPoint.y()); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + result.setX(matchingDataPoint.x()); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + result.setY(keyAxis->axisRect()->top()); + else + result.setY(keyAxis->axisRect()->bottom()); + } + } + return result; +} + +/*! \internal + + Returns the polygon needed for drawing normal fills between this graph and the key axis. + + Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment + which shall be used for the fill. The collection of \a lineData points described by \a segment + must not contain NaN data points (see \ref getNonNanSegments). + + The returned fill polygon will be closed at the key axis (the zero-value line) for linear value + axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect + side (see \ref getFillBasePoint). + + For increased performance (due to implicit sharing), keep the returned QPolygonF const. + + \see drawFill, getNonNanSegments +*/ +const QPolygonF QCPGraph::getFillPolygon(const QVector *lineData, QCPDataRange segment) const +{ + if (segment.size() < 2) + return QPolygonF(); + QPolygonF result(segment.size()+2); + + result[0] = getFillBasePoint(lineData->at(segment.begin())); + std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1); + result[result.size()-1] = getFillBasePoint(lineData->at(segment.end()-1)); + + return result; +} + +/*! \internal + + Returns the polygon needed for drawing (partial) channel fills between this graph and the graph + specified by \ref setChannelFillGraph. + + The data points of this graph are passed as pixel coordinates via \a thisData, the data of the + other graph as \a otherData. The returned polygon will be calculated for the specified data + segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a + otherData, respectively. + + The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by + \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap + need to be processed here. + + For increased performance due to implicit sharing, keep the returned QPolygonF const. + + \see drawFill, getOverlappingSegments, getNonNanSegments +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (thisData->isEmpty()) return QPolygonF(); + QVector thisSegmentData(thisSegment.size()); + QVector otherSegmentData(otherSegment.size()); + std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin()); + std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin()); + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisSegmentData; + QVector *croppedData = &otherSegmentData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // crop lower bound: + if (staticData->first().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + const int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li-1).x())) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // crop lower bound: + if (staticData->first().y() < croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() > croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisSegmentData << otherSegmentData.at(i); + return QPolygonF(thisSegmentData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is horizontal. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key + axis is vertical. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() < y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Calculates the minimum distance in pixels the graph's representation has from the given \a + pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if + the graph has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the graph line is also taken into account. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = (std::numeric_limits::max)(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + getLines(&lineData, QCPDataRange(0, dataCount())); // don't limit data range further since with sharp data spikes, line segments may be closer to test point than segments with closer key coordinate + QCPVector2D p(pixelPoint); + const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected + for (int i=0; i *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() > y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} +/* end of 'src/plottables/plottable-graph.cpp' */ + + +/* including file 'src/plottables/plottable-curve.cpp' */ +/* modified 2021-03-29T02:30:44, size 63851 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) + \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) + \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPCurveDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPCurveData::sortKey() const + + Returns the \a t member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). + All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() + + Since the member \a key is the data point key coordinate and the member \a t is the data ordering + parameter, this method returns false. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPCurveData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the curve's data via the \ref data method, which returns a pointer to the + internal \ref QCPCurveDataContainer. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpcurve-appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + + \section qcpcurve-usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPCurve::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mScatterSkip{}, + mLineStyle{} +{ + // modify inherited properties from abstract plottable: + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); + setScatterSkip(0); +} + +QCPCurve::~QCPCurve() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. + Modifying the data in the container will then affect all curves that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the curve's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 + + \see addData +*/ +void QCPCurve::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can + set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(t, keys, values, alreadySorted); +} + + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + \see addData +*/ +void QCPCurve::setData(const QVector &keys, const QVector &values) +{ + mDataContainer->clear(); + addData(keys, values); +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPCurve::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! \overload + + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (t.size() != keys.size() || t.size() != values.size()) + qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); + const int n = qMin(qMin(t.size(), keys.size()), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = t[i]; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &keys, const QVector &values) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + double tStart; + if (!mDataContainer->isEmpty()) + tStart = (mDataContainer->constEnd()-1)->t + 1.0; + else + tStart = 0; + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = tStart + i; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a t, \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double t, double key, double value) +{ + mDataContainer->add(QCPCurveData(t, key, value)); +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + The t parameter is generated automatically by increments of 1 for each point, starting at the + highest t of previously existing data or 0, if the curve data is empty. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double key, double value) +{ + if (!mDataContainer->isEmpty()) + mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); + else + mDataContainer->add(QCPCurveData(0.0, key, value)); +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = int( closestDataPoint-mDataContainer->constBegin() ); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + + // allocate line vector: + QVector lines, scatters; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + + // fill with curve data: + QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width + if (isSelectedSegment && mSelectionDecorator) + finalCurvePen = mSelectionDecorator->pen(); + + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) + getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); + + // check data validity if flag set: + #ifdef QCUSTOMPLOT_CHECK_DATA + for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->t) || + QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } + #endif + + // draw curve fill: + applyFillAntialiasingHint(painter); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(lines)); + + // draw curve line: + if (mLineStyle != lsNone) + { + painter->setPen(finalCurvePen); + painter->setBrush(Qt::NoBrush); + drawCurveLine(painter, lines); + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, getCurveLines +*/ +void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawCurveLine, getCurveLines +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + foreach (const QPointF &point, points) + if (!qIsNaN(point.x()) && !qIsNaN(point.y())) + style.drawShape(painter, point); +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the line of the + curve. + + Line segments that aren't visible in the current axis rect are handled in an optimized way. They + are projected onto a rectangle slightly larger than the visible axis rect and simplified + regarding point count. The algorithm makes sure to preserve appearance of lines and fills inside + the visible axis rect by generating new temporary points on the outer rect if necessary. + + \a lines will be filled with points in pixel coordinates, that can be drawn with \ref + drawCurveLine. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \a penWidth specifies the pen width that will be used to later draw the lines generated by this + function. This is needed here to calculate an accordingly wider margin around the axis rect when + performing the line optimization. + + Methods that are also involved in the algorithm are: \ref getRegion, \ref getOptimizedPoint, \ref + getOptimizedCornerPoints \ref mayTraverse, \ref getTraverse, \ref getTraverseCornerPoints. + + \see drawCurveLine, drawScatterPlot +*/ +void QCPCurve::getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const +{ + if (!lines) return; + lines->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety + const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); + const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); + const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); + const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); + QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); + if (itBegin == itEnd) + return; + QCPCurveDataContainer::const_iterator it = itBegin; + QCPCurveDataContainer::const_iterator prevIt = itEnd-1; + int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != itEnd) + { + const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != itBegin) + { + *lines << beforeTraverseCornerPoints; + lines->append(crossA); + lines->append(crossB); + *lines << afterTraverseCornerPoints; + } else + { + lines->append(crossB); + *lines << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + else + lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); + lines->append(coordsToPixels(it->key, it->value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lines->append(coordsToPixels(it->key, it->value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lines << trailingPoints; +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the scatters of the + curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly + sparser. + + Scatters that aren't visible in the current axis rect are optimized away. + + \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref + drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. + + \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel + coordinates generated by this function. This is needed here to calculate an accordingly wider + margin around the axis rect when performing the data point reduction. + + \see draw, drawScatterPlot +*/ +void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const +{ + if (!scatters) return; + scatters->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); + if (begin == end) + return; + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int endIndex = int( end-mDataContainer->constBegin() ); + + QCPRange keyRange = keyAxis->range(); + QCPRange valueRange = valueAxis->range(); + // extend range to include width of scatter symbols: + keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); + keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); + valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); + valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); + + QCPCurveDataContainer::const_iterator it = begin; + int itIndex = int( begin-mDataContainer->constBegin() ); + while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++itIndex; + ++it; + } + if (keyAxis->orientation() == Qt::Vertical) + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } else + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + It returns the region of the given point (\a key, \a value) with respect to a rectangle defined + by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. + + The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a + keyMin to \a keyMax): + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + if (key < keyMin) // region 123 + { + if (value > valueMax) + return 1; + else if (value < valueMin) + return 3; + else + return 2; + } else if (key > keyMax) // region 789 + { + if (value > valueMax) + return 7; + else if (value < valueMin) + return 9; + else + return 8; + } else // region 456 + { + if (value > valueMax) + return 4; + else if (value < valueMin) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double otherValuePx = mValueAxis->coordToPixel(otherValue); + const double valuePx = mValueAxis->coordToPixel(value); + const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); + const double keyPx = mKeyAxis->coordToPixel(key); + double intersectKeyPx = keyMinPx; // initial key just a fail-safe + double intersectValuePx = valueMinPx; // initial value just a fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 2: // left edge + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 3: // bottom and left edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMinPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 4: // top edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + break; + } + case 7: // top and right edge + { + intersectValuePx = valueMaxPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + case 8: // right edge + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + break; + } + case 9: // bottom and right edge + { + intersectValuePx = valueMinPx; + intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx); + if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed) + { + intersectKeyPx = keyMaxPx; + intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx); + } + break; + } + } + if (mKeyAxis->orientation() == Qt::Horizontal) + return {intersectKeyPx, intersectValuePx}; + else + return {intersectValuePx, intersectKeyPx}; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMax); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } + case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + else + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMin); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); break; } + case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + else + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(keyMax, valueMax); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); break; } + case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + else + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(keyMax, valueMin); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + else + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const +{ + // The intersection point interpolation here is done in pixel coordinates, so we don't need to + // differentiate between different axis scale types. Note that the nomenclature + // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be + // different in pixel coordinates (horz/vert key axes, reversed ranges) + + QList intersections; + const double valueMinPx = mValueAxis->coordToPixel(valueMin); + const double valueMaxPx = mValueAxis->coordToPixel(valueMax); + const double keyMinPx = mKeyAxis->coordToPixel(keyMin); + const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); + const double keyPx = mKeyAxis->coordToPixel(key); + const double valuePx = mValueAxis->coordToPixel(value); + const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); + const double prevValuePx = mValueAxis->coordToPixel(prevValue); + if (qFuzzyIsNull(keyPx-prevKeyPx)) // line is parallel to value axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx)); + } else if (qFuzzyIsNull(valuePx-prevValuePx)) // line is parallel to key axis + { + // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx)); + } else // line is skewed + { + double gamma; + double keyPerValuePx = (keyPx-prevKeyPx)/(valuePx-prevValuePx); + // check top of rect: + gamma = prevKeyPx + (valueMaxPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma)); + // check bottom of rect: + gamma = prevKeyPx + (valueMinPx-prevValuePx)*keyPerValuePx; + if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma)); + const double valuePerKeyPx = 1.0/keyPerValuePx; + // check left of rect: + gamma = prevValuePx + (keyMinPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx)); + // check right of rect: + gamma = prevValuePx + (keyMaxPx-prevKeyPx)*valuePerKeyPx; + if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed + intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + double xDelta = keyPx-prevKeyPx; + double yDelta = valuePx-prevValuePx; + if (mKeyAxis->orientation() != Qt::Horizontal) + qSwap(xDelta, yDelta); + if (xDelta*(intersections.at(1).x()-intersections.at(0).x()) + yDelta*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = intersections.at(0); + crossB = intersections.at(1); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that + if the curve has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the curve line is also taken into account. + + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns + -1.0. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + if (mDataContainer->size() == 1) + { + QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); + closestData = mDataContainer->constBegin(); + return QCPVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distances to curve data points and find closestData iterator: + double minDistSqr = (std::numeric_limits::max)(); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + QVector lines; + getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width + for (int i=0; i QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns \c nullptr. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return nullptr; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + const QList oldBars = mBars; + foreach (QCPBars *bars, oldBars) + bars->setBarsGroup(nullptr); // removes itself from mBars via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(nullptr); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else + { + double lowerPixelWidth, upperPixelWidth; + int startIndex; + int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+dir; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + // correct sign of result depending on orientation and direction of key axis: + result *= dir*thisBase->keyAxis()->pixelOrientation(); + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get access to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) + \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPBarsDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPBarsData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPBarsData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarsData::QCPBarsData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarsData::QCPBarsData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section qcpbars-appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section qcpbars-usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns \c nullptr. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns \c nullptr. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(nullptr), + mBaseValue(0), + mStackingGap(1) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPBars::~QCPBars() +{ + setBarsGroup(nullptr); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. + Modifying the data in the container will then affect all bars that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the bar's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 + + \see addData +*/ +void QCPBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to \c nullptr. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method + allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by + the bars below it. +*/ +void QCPBars::setStackingGap(double pixels) +{ + mStackingGap = pixels; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(double key, double value) +{ + mDataContainer->add(QCPBarsData(key, value)); +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to \c nullptr. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to \c nullptr. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getBarRect(it->key, it->value))) + result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false); + } + result.simplify(); + return result; +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + // get visible data range: + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getBarRect(it->key, it->value).contains(pos)) + { + if (details) + { + int pointIndex = int(it-mDataContainer->constBegin()); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return mParentPlot->selectionTolerance()*0.99; + } + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in + absolute pixels), using this method to adapt the key axis range to fit the bars into the + currently visible axis range will not work perfectly. Because in the moment the axis range is + changed to the new range, the fixed pixel widths/spacings will represent different coordinate + spans than before, which in turn would require a different key range to perfectly fit, and so on. + The only solution would be to iteratively approach the perfect fitting axis range, but the + mismatch isn't large enough in most applications, to warrant this here. If a user does need a + better fit, he should call the corresponding axis rescale multiple times in a row. + */ + QCPRange range; + range = mDataContainer->keyRange(foundRange, inSignDomain); + + // determine exact range of bars by including bar width and barsgroup offset: + if (foundRange && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + // lower range bound: + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) + range.lower = lowerCorrected; + // upper range bound: + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) + range.upper = upperCorrected; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + // Note: can't simply use mDataContainer->valueRange here because we need to + // take into account bar base value and possible stacking of multiple bars + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (inKeyRange != QCPRange()) + { + itBegin = mDataContainer->findBegin(inKeyRange.lower, false); + itEnd = mDataContainer->findEnd(inKeyRange.upper, false); + } + for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + +/* inherits documentation from base class */ +QPointF QCPBars::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } + + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); + const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); + if (keyAxis->orientation() == Qt::Horizontal) + return {keyPixel, valuePixel}; + else + return {valuePixel, keyPixel}; + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return {}; + } +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mDataContainer->isEmpty()) return; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPBarsDataContainer::const_iterator begin = visibleBegin; + QCPBarsDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +#endif + // draw bar: + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyBrush(painter); + mSelectionDecorator->applyPen(painter); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + } + applyDefaultAntialiasingHint(painter); + painter->drawPolygon(getBarRect(it->key, it->value)); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + if (mDataContainer->isEmpty()) + { + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + + // get visible data range as QMap iterators + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from begin to find lower bar that actually is completely outside visible pixel range: + QCPBarsDataContainer::const_iterator it = begin; + while (it != mDataContainer->constBegin()) + { + --it; + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); + if (isVisible) + begin = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = end; + while (it != mDataContainer->constEnd()) + { + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); + if (isVisible) + end = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The + rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue), and to have non-overlapping border lines with the bars stacked below. +*/ +QRectF QCPBars::getBarRect(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } + + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); + bottomOffset += mBarBelow ? mStackingGap : 0; + bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); + if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) + bottomOffset = valuePixel-basePixel; + if (keyAxis->orientation() == Qt::Horizontal) + { + return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); + } else + { + return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + lower = 0; + upper = 0; + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point + if (key == 0) + epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); + QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); + QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); + while (it != itEnd) + { + if (it->key > key-epsilon && it->key < key+epsilon) + { + if ((positive && it->value > max) || + (!positive && it->value < max)) + max = it->value; + } + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = nullptr; + upper->mBarBelow = nullptr; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = nullptr; + lower->mBarAbove = nullptr; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = nullptr; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = nullptr; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} +/* end of 'src/plottables/plottable-bars.cpp' */ + + +/* including file 'src/plottables/plottable-statisticalbox.cpp' */ +/* modified 2021-03-29T02:30:44, size 28951 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBoxData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBoxData + \brief Holds the data of one single data point for QCPStatisticalBox. + + The stored data is: + + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the + sample that's not considered an outlier. + + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a median: the value of the median mark inside the quartile box. The median separates the + sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) + + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the + sample that's not considered an outlier. + + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key + coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) + + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a + typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template + parameter. See the documentation there for an explanation regarding the data type's generic + methods. + + \see QCPStatisticalBoxDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPStatisticalBoxData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainValue() const + + Returns the \a median member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const + + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box + data point, possibly further expanded by outliers. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData() : + key(0), + minimum(0), + lowerQuartile(0), + median(0), + upperQuartile(0), + maximum(0) +{ +} + +/*! + Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a + upperQuartile, \a maximum and optionally a number of \a outliers. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : + key(key), + minimum(minimum), + lowerQuartile(lowerQuartile), + median(median), + upperQuartile(upperQuartile), + maximum(maximum), + outliers(outliers) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPStatisticalBoxDataContainer. + + Additionally each data point can itself have a list of outliers, drawn as scatter points at the + key coordinate of the respective statistical box data point. They can either be set by using the + respective \ref addData(double,double,double,double,double,double,const QVector&) + "addData" method or accessing the individual data points through \ref data, and setting the + QVector outliers of the data points directly. + + \section qcpstatisticalbox-appearance Changing the appearance + + The appearance of each data point box, ranging from the lower to the upper quartile, is + controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref + setWidth in plot coordinates. + + Each data point's visual representation also consists of two whiskers. Whiskers are the lines + which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. + The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, + \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at + the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set + the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a + few pixels due to the pen cap being not perfectly flat. + + The median indicator line inside the box has its own pen, \ref setMedianPen. + + The outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section qcpstatisticalbox-usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/* start documentation of inline functions */ + +/*! \fn QSharedPointer QCPStatisticalBox::data() const + + Returns a shared pointer to the internal data storage of type \ref + QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more + convenient and faster than using the regular \ref setData or \ref addData methods. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not + delete it manually but use QCustomPlot::removePlottable() instead. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.5), + mWhiskerWidth(0.2), + mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), + mWhiskerBarPen(Qt::black), + mWhiskerAntialiased(false), + mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), + mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) +{ + setPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container + safely. Modifying the data in the container will then affect all statistical boxes that share the + container. Sharing can be achieved by simply exchanging the data containers wrapped in shared + pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the statistical box data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 + + \see addData +*/ +void QCPStatisticalBox::setData(QSharedPointer data) +{ + mDataContainer = data; +} +/*! \overload + + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a + median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the + number of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); +} + +/*! + Sets the width of the boxes in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers in key coordinates. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone + line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at + each end of the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets whether the statistical boxes whiskers are drawn with antialiasing or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) +{ + mWhiskerAntialiased = enabled; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical boxes. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + Outliers can be specified with the method + \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/*! \overload + + Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and + \a maximum to the current data. The provided vectors should have equal length. Else, the number + of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || + median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" + << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); + const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->minimum = minimum[i]; + it->lowerQuartile = lowerQuartile[i]; + it->median = median[i]; + it->upperQuartile = upperQuartile[i]; + it->maximum = maximum[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile + and \a maximum to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +{ + mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getQuartileBox(it))) + result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false); + } + result.simplify(); + return result; +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + // get visible data range: + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + double minDistSqr = (std::numeric_limits::max)(); + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getQuartileBox(it).contains(pos)) // quartile box + { + double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } else // whiskers + { + const QVector whiskerBackbones = getWhiskerBackboneLines(it); + const QCPVector2D posVec(pos); + foreach (const QLineF &backbone, whiskerBackbones) + { + double currentDistSqr = posVec.distanceSquaredToLine(backbone); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + } + if (details) + { + int pointIndex = int(closestDataPoint-mDataContainer->constBegin()); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return qSqrt(minDistSqr); + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; + QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +# ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->minimum) || + QCP::isInvalidData(it->lowerQuartile, it->median) || + QCP::isInvalidData(it->upperQuartile, it->maximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; ioutliers.size(); ++i) + if (QCP::isInvalidData(it->outliers.at(i))) + qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +# endif + + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + QCPScatterStyle finalOutlierStyle = mOutlierStyle; + if (isSelectedSegment && mSelectionDecorator) + finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); + drawStatisticalBox(painter, it, finalOutlierStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! + Draws the graphical representation of a single statistical box with the data given by the + iterator \a it with the provided \a painter. + + If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. + + \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const +{ + // draw quartile box: + applyDefaultAntialiasingHint(painter); + const QRectF quartileBox = getQuartileBox(it); + painter->drawRect(quartileBox); + // draw median line with cliprect set to quartile box: + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + painter->setPen(mMedianPen); + painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); + painter->restore(); + // draw whisker lines: + applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); + painter->setPen(mWhiskerPen); + painter->drawLines(getWhiskerBackboneLines(it)); + painter->setPen(mWhiskerBarPen); + painter->drawLines(getWhiskerBarLines(it)); + // draw outliers: + applyScattersAntialiasingHint(painter); + outlierStyle.applyTo(painter, mPen); + for (int i=0; ioutliers.size(); ++i) + outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points +} + +/*! \internal + + Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the + value range from the lower to the upper quartile, of the data given by \a it. + + \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QRectF result; + result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); + result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); + return result; +} + +/*! \internal + + Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value + range from the minimum to the lower quartile, and from the upper quartile to the maximum of the + data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines +*/ +QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone + result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone + return result; +} + +/*! \internal + + Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the + end of the whisker backbones, at the minimum and maximum of the data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines +*/ +QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar + result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar + return result; +} +/* end of 'src/plottables/plottable-statisticalbox.cpp' */ + + +/* including file 'src/plottables/plottable-colormap.cpp' */ +/* modified 2021-03-29T02:30:44, size 48149 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if + allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref + fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on + the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(nullptr), + mAlpha(nullptr), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + delete[] mData; + delete[] mAlpha; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(nullptr), + mAlpha(nullptr), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. The alpha map state is + transferred, too. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + if (!other.mAlpha && mAlpha) + clearAlpha(); + setSize(keySize, valueSize); + if (other.mAlpha && !mAlpha) + createAlpha(false); + setRange(other.keyRange(), other.valueRange()); + if (!isEmpty()) + { + memcpy(mData, other.mData, sizeof(mData[0])*size_t(keySize*valueSize)); + if (mAlpha) + memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*size_t(keySize*valueSize)); + } + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = int( (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5 ); + int valueCell = int( (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5 ); + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. + + If this color map data doesn't have an alpha map (because \ref setAlpha was never called after + creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. + + \see setAlpha +*/ +unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) +{ + if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mAlpha[valueIndex*mKeySize + keyIndex]; + else + return 255; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[size_t(mKeySize*mValueSize)]; +#ifdef __EXCEPTIONS + } catch (...) { mData = nullptr; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = nullptr; + + if (mAlpha) // if we had an alpha map, recreate it with new size + createAlpha(); + + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = int( (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5 ); + int valueCell = int( (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5 ); + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value + of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully + opaque cell. + + If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish + to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. + + Note that the cell-wise alpha which can be configured here is independent of any alpha configured + in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise + and gradient alpha, the alpha values will be blended accordingly during rendering of the color + map. + + \see fillAlpha, clearAlpha +*/ +void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + if (mAlpha || createAlpha()) + { + mAlpha[valueIndex*mKeySize + keyIndex] = alpha; + mDataModified = true; + } + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Frees the internal alpha map. The color map will have full opacity again. +*/ +void QCPColorMapData::clearAlpha() +{ + if (mAlpha) + { + delete[] mAlpha; + mAlpha = nullptr; + mDataModified = true; + } +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass \c nullptr as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + { + if (details) + details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (inKeyRange != QCPRange()) + { + if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) + { + foundRange = false; + return {}; + } + } + + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(keySize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(valueSize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); + + if (mMapImage.isNull()) + { + qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; + mMapImage = QImage(QSize(10, 10), format); + mMapImage.fill(Qt::black); + } else + { + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + const unsigned char *rawAlpha = mMapData->mAlpha; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + if (useBuffer) + { + const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/double(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/double(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/double(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/double(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} +/* end of 'src/plottables/plottable-colormap.cpp' */ + + +/* including file 'src/plottables/plottable-financial.cpp' */ +/* modified 2021-03-29T02:30:44, size 42914 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a open: The opening value at the data point (this is the \a mainValue) + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef + for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPFinancialDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPFinancialData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainValue() const + + Returns the \a open member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPFinancialData::valueRange() const + + Returns a QCPRange spanning from the \a low to the \a high value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref + setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and + the width to (or slightly less than) one time bin interval width. + + \section qcpfinancial-appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, + irrespective of whether the chart is single- or two-colored. + + \section qcpfinancial-usage Usage + + Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot + instance takes ownership of the plottable, so do not delete it manually but use + QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 + Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data + series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mChartStyle(csCandlestick), + mWidth(0.5), + mWidthType(wtPlotCoords), + mTwoColored(true), + mBrushPositive(QBrush(QColor(50, 160, 0))), + mBrushNegative(QBrush(QColor(180, 0, 15))), + mPenPositive(QPen(QColor(40, 150, 0))), + mPenNegative(QPen(QColor(170, 5, 5))) +{ + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPFinancial::~QCPFinancial() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. + Modifying the data in the container will then affect all financials that share the container. + Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the financial's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a + close. The provided vectors should have equal length. Else, the number of added points will be + the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, open, high, low, close, alreadySorted); +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for + an explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! \overload + + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. + The provided vectors should have equal length. Else, the number of added points will be the size + of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); + const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->open = open[i]; + it->high = high[i]; + it->low = low[i]; + it->close = close[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current + data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mDataContainer->add(QCPFinancialData(key, open, high, low, close)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(selectionHitBox(it))) + result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false); + } + result.simplify(); + return result; +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + // perform select test according to configured style: + double result = -1; + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + case QCPFinancial::csCandlestick: + result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + } + if (details) + { + int pointIndex = int(closestDataPoint-mDataContainer->constBegin()); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } + + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const + QCPFinancialDataContainer&). + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataContainer data; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataContainer(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + data.add(currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + data.add(currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return data; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPFinancialDataContainer::const_iterator begin = visibleBegin; + QCPFinancialDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + // draw data segment according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, begin, end, isSelectedSegment); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); + } + } else + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); + } + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of + \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel + when this function is called). + + It returns the number of pixels the bar extends to higher keys, relative to the \a key + coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed + horizontal axis, the return value is negative. This is important so the open/close flags on the + \ref csOhlc bar are drawn to the correct side. +*/ +double QCPFinancial::getPixelWidth(double key, double keyPixel) const +{ + double result = 0; + switch (mWidthType) + { + case wtAbsolute: + { + if (mKeyAxis) + result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } + return result; +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = (std::numeric_limits::max)(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = (std::numeric_limits::max)(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + begin may still be just outside the visible range. + + \a end returns the iterator just above the highest data point that needs to be taken into + account. Same as before, \a end may also lie just outside of the visible range + + if the plottable contains no data, both \a begin and \a end point to \c constEnd. +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points +} + +/*! \internal + + Returns the hit box in pixel coordinates that will be used for data selection with the selection + rect (\ref selectTestRect), of the data point given by \a it. +*/ +QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; } + + double keyPixel = keyAxis->coordToPixel(it->key); + double highPixel = valueAxis->coordToPixel(it->high); + double lowPixel = valueAxis->coordToPixel(it->low); + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); + if (keyAxis->orientation() == Qt::Horizontal) + return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); + else + return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); +} +/* end of 'src/plottables/plottable-financial.cpp' */ + + +/* including file 'src/plottables/plottable-errorbar.cpp' */ +/* modified 2021-03-29T02:30:44, size 37679 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBarsData + \brief Holds the data of one single error bar for QCPErrorBars. + + The stored data is: + \li \a errorMinus: how much the error bar extends towards negative coordinates from the data + point position + \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point + position + + The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a + typedef for QVector<\ref QCPErrorBarsData>. + + \see QCPErrorBarsDataContainer +*/ + +/*! + Constructs an error bar with errors set to zero. +*/ +QCPErrorBarsData::QCPErrorBarsData() : + errorMinus(0), + errorPlus(0) +{ +} + +/*! + Constructs an error bar with equal \a error in both negative and positive direction. +*/ +QCPErrorBarsData::QCPErrorBarsData(double error) : + errorMinus(error), + errorPlus(error) +{ +} + +/*! + Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, + respectively. +*/ +QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : + errorMinus(errorMinus), + errorPlus(errorPlus) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBars + \brief A plottable that adds a set of error bars to other plottables. + + \image html QCPErrorBars.png + + The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref + QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. + + Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the + error bars. The orientation of the error bars can be controlled with \ref setErrorType. + + By using \ref setData, you can supply the actual error data, either as symmetric error or + plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute + key/value position of each error bar will be adopted from the configured data plottable. The + error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points + of the data plottable. You can directly access and manipulate the error bar data via \ref data. + + Set either of the plus/minus errors to NaN (qQNaN() or + std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at + that index. + + \section qcperrorbars-appearance Changing the appearance + + The appearance of the error bars is defined by the pen (\ref setPen), and the width of the + whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data + point center to prevent that error bars are drawn too close to or even through scatter points. + This gap size can be controlled via \ref setSymbolGap. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPErrorBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You + may use it to directly manipulate the error values, which may be more convenient and faster than + using the regular \ref setData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + It is also important that the \a keyAxis and \a valueAxis are the same for the error bars + plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). + + The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not + delete it manually but use \ref QCustomPlot::removePlottable() instead. +*/ +QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QVector), + mErrorType(etValueError), + mWhiskerWidth(9), + mSymbolGap(10) +{ + setPen(QPen(Qt::black, 0)); + setBrush(Qt::NoBrush); +} + +QCPErrorBars::~QCPErrorBars() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data + container safely. Modifying the data in the container will then affect all \ref QCPErrorBars + instances that share the container. Sharing can be achieved by simply exchanging the data + containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, assign the + data containers directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 + (This uses different notation compared with other plottables, because the \ref QCPErrorBars + uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) + + \see addData +*/ +void QCPErrorBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &error) +{ + mDataContainer->clear(); + addData(error); +} + +/*! \overload + + Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) +{ + mDataContainer->clear(); + addData(errorMinus, errorPlus); +} + +/*! + Sets the data plottable to which the error bars will be applied. The error values specified e.g. + via \ref setData will be associated one-to-one by the data point index to the data points of \a + plottable. This means that the error bars will adopt the key/value coordinates of the data point + with the same index. + + The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref + QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either + of these restrictions is violated, a corresponding qDebug output is generated, and the data + plottable of this \ref QCPErrorBars instance is set to zero. + + For proper display, care must also be taken that the key and value axes of the \a plottable match + those configured for this \ref QCPErrorBars instance. +*/ +void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) +{ + if (plottable && qobject_cast(plottable)) + { + mDataPlottable = nullptr; + qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; + return; + } + if (plottable && !plottable->interface1D()) + { + mDataPlottable = nullptr; + qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; + return; + } + + mDataPlottable = plottable; +} + +/*! + Sets in which orientation the error bars shall appear on the data points. If your data needs both + error dimensions, create two \ref QCPErrorBars with different \a type. +*/ +void QCPErrorBars::setErrorType(ErrorType type) +{ + mErrorType = type; +} + +/*! + Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to + \a pixels. +*/ +void QCPErrorBars::setWhiskerWidth(double pixels) +{ + mWhiskerWidth = pixels; +} + +/*! + Sets the gap diameter around the data points that will be left out when drawing the error bar + backbones. This gap prevents that error bars are drawn too close to or even through scatter + points. +*/ +void QCPErrorBars::setSymbolGap(double pixels) +{ + mSymbolGap = pixels; +} + +/*! \overload + + Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &error) +{ + addData(error, error); +} + +/*! \overload + + Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) +{ + if (errorMinus.size() != errorPlus.size()) + qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); + const int n = qMin(errorMinus.size(), errorPlus.size()); + mDataContainer->reserve(n); + for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); +} + +/*! \overload + + Adds a single symmetrical error bar as specified in \a error. The errors will be associated + one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double error) +{ + mDataContainer->append(QCPErrorBarsData(error)); +} + +/*! \overload + + Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors + will be associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double errorMinus, double errorPlus) +{ + mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); +} + +/* inherits documentation from base class */ +int QCPErrorBars::dataCount() const +{ + return mDataContainer->size(); +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataSortKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataSortKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainValue(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainValue(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::dataValueRange(int index) const +{ + if (mDataPlottable) + { + const double value = mDataPlottable->interface1D()->dataMainValue(index); + if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) + return {value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus}; + else + return {value, value}; + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return {}; + } +} + +/* inherits documentation from base class */ +QPointF QCPErrorBars::dataPixelPosition(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataPixelPosition(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return {}; +} + +/* inherits documentation from base class */ +bool QCPErrorBars::sortKeyIsMainKey() const +{ + if (mDataPlottable) + { + return mDataPlottable->interface1D()->sortKeyIsMainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return true; + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if (!mDataPlottable) + return result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); + + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + backbones.clear(); + whiskers.clear(); + getErrorBarLines(it, backbones, whiskers); + foreach (const QLineF &backbone, backbones) + { + if (rectIntersectsLine(rect, backbone)) + { + result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false); + break; + } + } + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); + if (beginIndex >= mDataContainer->size()) + beginIndex = mDataContainer->size()-1; + return beginIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); + if (endIndex > mDataContainer->size()) + endIndex = mDataContainer->size(); + return endIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/*! + Implements a selectTest specific to this plottable's point geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data + point to \a pos. + + \seebaseclassmethod \ref QCPAbstractPlottable::selectTest +*/ +double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mDataPlottable) return -1; + + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect)) + { + QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = int(closestDataPoint-mDataContainer->constBegin()); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +void QCPErrorBars::draw(QCPPainter *painter) +{ + if (!mDataPlottable) return; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually + // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): + bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); + } +#endif + + applyDefaultAntialiasingHint(painter); + painter->setBrush(Qt::NoBrush); + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + QVector backbones, whiskers; + for (int i=0; i= unselectedSegments.size(); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + if (painter->pen().capStyle() == Qt::SquareCap) + { + QPen capFixPen(painter->pen()); + capFixPen.setCapStyle(Qt::FlatCap); + painter->setPen(capFixPen); + } + backbones.clear(); + whiskers.clear(); + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (!checkPointVisibility || errorBarVisible(int(it-mDataContainer->constBegin()))) + getErrorBarLines(it, backbones, whiskers); + } + painter->drawLines(backbones); + painter->drawLines(whiskers); + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) + { + painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); + painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); + painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); + } else + { + painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); + painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); + painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); + } +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + if (!mDataPlottable) + { + foundRange = false; + return {}; + } + + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (mErrorType == etValueError) + { + // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainKey(int(it-mDataContainer->constBegin())); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } else // mErrorType == etKeyError + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(int(it-mDataContainer->constBegin())); + if (qIsNaN(dataKey)) continue; + // plus error: + double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (!mDataPlottable) + { + foundRange = false; + return {}; + } + + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower, false); + itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper, false); + } + for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange) + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(int(it-mDataContainer->constBegin())); + if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) + continue; + } + if (mErrorType == etValueError) + { + const double dataValue = mDataPlottable->interface1D()->dataMainValue(int(it-mDataContainer->constBegin())); + if (qIsNaN(dataValue)) continue; + // plus error: + double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } else // mErrorType == etKeyError + { + // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainValue(int(it-mDataContainer->constBegin())); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Calculates the lines that make up the error bar belonging to the data point \a it. + + The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so + calling this method with different \a it but the same \a backbones and \a whiskers allows to + accumulate lines for multiple data points. + + This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars + instance and within the bounds of the associated data plottable. +*/ +void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const +{ + if (!mDataPlottable) return; + + int index = int(it-mDataContainer->constBegin()); + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) + return; + QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); + QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); + const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value + const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); + // plus error: + double errorStart, errorEnd; + if (!qIsNaN(it->errorPlus)) + { + errorStart = centerErrorAxisPixel+symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } + // minus error: + if (!qIsNaN(it->errorMinus)) + { + errorStart = centerErrorAxisPixel-symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } +} + +/*! \internal + + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key + coordinates relative to their data point key, this method checks all outer error bars whether + they truly don't reach into the visible portion of the axis rect, by calling \ref + errorBarVisible. On the other hand error bars with type \ref etValueError that are associated + with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype + "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of + error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref + QCPPlottableInterface1D::findEnd). + + If the plottable's sort key is not equal to the main key, this method returns the full data + range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a + point-by-point basis in the \ref draw method. +*/ +void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable || rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) + { + // if the sort key isn't the main key, it's not possible to find a contiguous range of visible + // data points, so this method then only applies the range restriction and otherwise returns + // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing + QCPDataRange dataRange(0, mDataContainer->size()); + dataRange = dataRange.bounded(rangeRestriction); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); + return; + } + + // get visible data range via interface from data plottable, and then restrict to available error data points: + const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); + int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); + int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); + int i = beginIndex; + while (i > 0 && i < n && i > rangeRestriction.begin()) + { + if (errorBarVisible(i)) + beginIndex = i; + --i; + } + i = endIndex; + while (i >= 0 && i < n && i < rangeRestriction.end()) + { + if (errorBarVisible(i)) + endIndex = i+1; + ++i; + } + QCPDataRange dataRange(beginIndex, endIndex); + dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); +} + +/*! \internal + + Calculates the minimum distance in pixels the error bars' representation has from the given \a + pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. +*/ +double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (!mDataPlottable || mDataContainer->isEmpty()) + return -1.0; + if (!mKeyAxis || !mValueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + return -1.0; + } + + QCPErrorBarsDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); + + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: + double minDistSqr = (std::numeric_limits::max)(); + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + getErrorBarLines(it, backbones, whiskers); + foreach (const QLineF &backbone, backbones) + { + const double currentDistSqr = QCPVector2D(pixelPoint).distanceSquaredToLine(backbone); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + \note This method is identical to \ref QCPAbstractPlottable1D::getDataSegments but needs to be + reproduced here since the \ref QCPErrorBars plottable, as a special case that doesn't have its + own key/value data coordinates, doesn't derive from \ref QCPAbstractPlottable1D. See the + documentation there for details. +*/ +void QCPErrorBars::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! \internal + + Returns whether the error bar at the specified \a index is visible within the current key axis + range. + + This method assumes for performance reasons without checking that the key axis, the value axis, + and the data plottable (\ref setDataPlottable) are not \c nullptr and that \a index is within + valid bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. +*/ +bool QCPErrorBars::errorBarVisible(int index) const +{ + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + if (qIsNaN(centerKeyPixel)) + return false; + + double keyMin, keyMax; + if (mErrorType == etKeyError) + { + const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); + const double errorPlus = mDataContainer->at(index).errorPlus; + const double errorMinus = mDataContainer->at(index).errorMinus; + keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); + keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); + } else // mErrorType == etValueError + { + keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + } + return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); +} + +/*! \internal + + Returns whether \a line intersects (or is contained in) \a pixelRect. + + \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for + error bar lines. +*/ +bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const +{ + if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) + return false; + else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) + return false; + else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) + return false; + else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) + return false; + else + return true; +} +/* end of 'src/plottables/plottable-errorbar.cpp' */ + + +/* including file 'src/items/item-straightline.cpp' */ +/* modified 2021-03-29T02:30:44, size 7596 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QCPVector2D start(point1->pixelPosition()); + QCPVector2D end(point2->pixelPosition()); + // get visible segment of straight line inside clipRect: + int clipPad = qCeil(mainPen().widthF()); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-straightline.cpp' */ + + +/* including file 'src/items/item-line.cpp' */ +/* modified 2021-03-29T02:30:44, size 8525 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QCPVector2D startVec(start->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if (qFuzzyIsNull((startVec-endVec).lengthSquared())) + return; + // get visible segment of straight line inside clipRect: + int clipPad = int(qMax(mHead.boundingDistance(), mTail.boundingDistance())); + clipPad = qMax(clipPad, qCeil(mainPen().widthF())); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(qRound(start.x()), qRound(start.y())); + bool containsEnd = rect.contains(qRound(end.x()), qRound(end.y())); + if (containsStart && containsEnd) + return {start.toPointF(), end.toPointF()}; + + QCPVector2D base = start; + QCPVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-line.cpp' */ + + +/* including file 'src/items/item-curve.cpp' */ +/* modified 2021-03-29T02:30:44, size 7273 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPosition()); + QPointF startDirVec(startDir->pixelPosition()); + QPointF endDirVec(endDir->pixelPosition()); + QPointF endVec(end->pixelPosition()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QList polygons = cubicPath.toSubpathPolygons(); + if (polygons.isEmpty()) + return -1; + const QPolygonF polygon = polygons.first(); + QCPVector2D p(pos); + double minDistSqr = (std::numeric_limits::max)(); + for (int i=1; ipixelPosition()); + QCPVector2D startDirVec(startDir->pixelPosition()); + QCPVector2D endDirVec(endDir->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if ((endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec.toPointF()); + cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); + + // paint visible segment, if existent: + const int clipEnlarge = qCeil(mainPen().widthF()); + QRect clip = clipRect().adjusted(-clipEnlarge, -clipEnlarge, clipEnlarge, clipEnlarge); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-curve.cpp' */ + + +/* including file 'src/items/item-rect.cpp' */ +/* modified 2021-03-29T02:30:44, size 6472 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return {}; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-rect.cpp' */ + + +/* including file 'src/items/item-text.cpp' */ +/* modified 2021-03-29T02:30:44, size 13335 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mText(QLatin1String("text")), + mPositionAlignment(Qt::AlignCenter), + mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), + mRotation(0) +{ + position->setCoords(0, 0); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectDistance function for non-rotated rects: + QPointF positionPixels(position->pixelPosition()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectDistance(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPosition()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + int clipPad = qCeil(mainPen().widthF()); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPosition(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPosition()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return {}; +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-text.cpp' */ + + +/* including file 'src/items/item-ellipse.cpp' */ +/* modified 2021-03-29T02:30:44, size 7881 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + double result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + const int clipEnlarge = qCeil(mainPen().widthF()); + QRect clip = clipRect().adjusted(-clipEnlarge, -clipEnlarge, clipEnlarge, clipEnlarge); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return {}; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-ellipse.cpp' */ + + +/* including file 'src/items/item-pixmap.cpp' */ +/* modified 2021-03-29T02:30:44, size 10622 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaled(false), + mScaledPixmapInvalidated(true), + mAspectRatioMode(Qt::KeepAspectRatio), + mTransformationMode(Qt::SmoothTransformation) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectDistance(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + int clipPad = mainPen().style() == Qt::NoPen ? 0 : qCeil(mainPen().widthF()); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return {}; +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + double devicePixelRatio = mPixmap.devicePixelRatio(); +#else + double devicePixelRatio = 1.0; +#endif + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) + { + mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mScaledPixmap.setDevicePixelRatio(devicePixelRatio); +#endif + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPosition().toPoint(); + QPoint p2 = bottomRight->pixelPosition().toPoint(); + if (p1 == p2) + return {p1, QSize(0, 0)}; + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + scaledSize /= mPixmap.devicePixelRatio(); + scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); +#else + scaledSize.scale(newSize, mAspectRatioMode); +#endif + result = QRect(topLeft, scaledSize); + } else + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); +#else + result = QRect(p1, mPixmap.size()); +#endif + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-pixmap.cpp' */ + + +/* including file 'src/items/item-tracer.cpp' */ +/* modified 2021-03-29T02:30:44, size 14645 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mSize(6), + mStyle(tsCrosshair), + mGraph(nullptr), + mGraphKey(0), + mInterpolating(false) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to \c nullptr. The tracer \a position can then be + placed freely like any other item position. This is the state the tracer will assume when its + graph gets deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = nullptr; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), + QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), + QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QCPVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { +// if (center.y() > clip.top() && center.y() < clip.bottom()) +// painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); + QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey <= first->key) + position->setCoords(first->key, first->value); + else if (mGraphKey >= last->key) + position->setCoords(last->key, last->value); + else + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); + if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators + { + QCPGraphDataContainer::const_iterator prevIt = it; + ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare(double(it->key), double(prevIt->key))) + slope = (it->value-prevIt->value)/(it->key-prevIt->key); + position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt->key+it->key)*0.5) + position->setCoords(prevIt->key, prevIt->value); + else + position->setCoords(it->key, it->value); + } + } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) + position->setCoords(it->key, it->value); + } + } else if (mGraph->data()->size() == 1) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it->key, it->value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-tracer.cpp' */ + + +/* including file 'src/items/item-bracket.cpp' */ +/* modified 2021-03-29T02:30:44, size 10705 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)), + mLength(8), + mStyle(bsCalligraphic) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QCPVector2D p(pos); + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); + double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); + double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + const int clipEnlarge = qCeil(mainPen().widthF()); + QRect clip = clipRect().adjusted(-clipEnlarge, -clipEnlarge, clipEnlarge, clipEnlarge); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return {}; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-bracket.cpp' */ + + +/* including file 'src/polar/radialaxis.cpp' */ +/* modified 2021-03-29T02:30:44, size 49415 */ + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPolarAxisRadial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPolarAxisRadial + \brief The radial axis inside a radial plot + + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and + functionality to be incomplete, as well as changing public interfaces in the future. + + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPPolarAxisRadial::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPPolarAxisRadial::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPPolarAxisRadial::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPPolarAxisRadial::scaleTypeChanged(QCPPolarAxisRadial::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPPolarAxisRadial::selectionChanged(QCPPolarAxisRadial::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPPolarAxisRadial::selectableChanged(const QCPPolarAxisRadial::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPPolarAxisRadial::QCPPolarAxisRadial(QCPPolarAxisAngular *parent) : + QCPLayerable(parent->parentPlot(), QString(), parent), + mRangeDrag(true), + mRangeZoom(true), + mRangeZoomFactor(0.85), + // axis base: + mAngularAxis(parent), + mAngle(45), + mAngleReference(arAngularAxis), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabelPadding(0), + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + // mTickLabelPadding(0), in label painter + mTickLabels(true), + // mTickLabelRotation(0), in label painter + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + mNumberMultiplyCross(false), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickLengthIn(5), + mTickLengthOut(0), + mSubTickLengthIn(2), + mSubTickLengthOut(0), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mRadius(1), // non-zero initial value, will be overwritten in ::update() according to inner rect + mTicker(new QCPAxisTicker), + mLabelPainter(mParentPlot) +{ + setParent(parent); + setAntialiased(true); + + setTickLabelPadding(5); + setTickLabelRotation(0); + setTickLabelMode(lmUpright); + mLabelPainter.setAnchorReferenceType(QCPLabelPainterPrivate::artTangent); + mLabelPainter.setAbbreviateDecimalPowers(false); +} + +QCPPolarAxisRadial::~QCPPolarAxisRadial() +{ +} + +QCPPolarAxisRadial::LabelMode QCPPolarAxisRadial::tickLabelMode() const +{ + switch (mLabelPainter.anchorMode()) + { + case QCPLabelPainterPrivate::amSkewedUpright: return lmUpright; + case QCPLabelPainterPrivate::amSkewedRotated: return lmRotated; + default: qDebug() << Q_FUNC_INFO << "invalid mode for polar axis"; break; + } + return lmUpright; +} + +/* No documentation as it is a property getter */ +QString QCPPolarAxisRadial::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mNumberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPPolarAxisRadial::tickLengthIn() const +{ + return mTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPPolarAxisRadial::tickLengthOut() const +{ + return mTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPPolarAxisRadial::subTickLengthIn() const +{ + return mSubTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPPolarAxisRadial::subTickLengthOut() const +{ + return mSubTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPPolarAxisRadial::labelPadding() const +{ + return mLabelPadding; +} + +void QCPPolarAxisRadial::setRangeDrag(bool enabled) +{ + mRangeDrag = enabled; +} + +void QCPPolarAxisRadial::setRangeZoom(bool enabled) +{ + mRangeZoom = enabled; +} + +void QCPPolarAxisRadial::setRangeZoomFactor(double factor) +{ + mRangeZoomFactor = factor; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. For logarithmic scales, you will + likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting + the axis ticker to an instance of \ref QCPAxisTickerLog : + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpaxisticker-log-creation + + See the documentation of \ref QCPAxisTickerLog about the details of logarithmic axis tick + creation. + + \ref setNumberPrecision +*/ +void QCPPolarAxisRadial::setScaleType(QCPPolarAxisRadial::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + //mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPPolarAxisRadial::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPPolarAxisRadial::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPPolarAxisRadial::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPPolarAxisRadial::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPPolarAxisRadial::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPPolarAxisRadial::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPPolarAxisRadial::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPPolarAxisRadial::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +void QCPPolarAxisRadial::setAngle(double degrees) +{ + mAngle = degrees; +} + +void QCPPolarAxisRadial::setAngleReference(AngleReference reference) +{ + mAngleReference = reference; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPPolarAxisRadial::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPPolarAxisRadial::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + //mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPPolarAxisRadial::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + //mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPPolarAxisRadial::setTickLabelPadding(int padding) +{ + mLabelPainter.setPadding(padding); +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPPolarAxisRadial::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + //mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPPolarAxisRadial::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPPolarAxisRadial::setTickLabelRotation(double degrees) +{ + mLabelPainter.setRotation(degrees); +} + +void QCPPolarAxisRadial::setTickLabelMode(LabelMode mode) +{ + switch (mode) + { + case lmUpright: mLabelPainter.setAnchorMode(QCPLabelPainterPrivate::amSkewedUpright); break; + case lmRotated: mLabelPainter.setAnchorMode(QCPLabelPainterPrivate::amSkewedRotated); break; + } +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPPolarAxisRadial::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + //mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mNumberMultiplyCross = false; + } else + { + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + mNumberBeautifulPowers = true; + else + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + + if (formatCode.length() < 3) + { + mNumberMultiplyCross = false; + } else + { + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + mNumberMultiplyCross = true; + else if (formatCode.at(2) == QLatin1Char('d')) + mNumberMultiplyCross = false; + else + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + } + } + mLabelPainter.setSubstituteExponent(mNumberBeautifulPowers); + mLabelPainter.setMultiplicationSymbol(mNumberMultiplyCross ? QCPLabelPainterPrivate::SymbolCross : QCPLabelPainterPrivate::SymbolDot); +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPPolarAxisRadial::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + //mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPPolarAxisRadial::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPPolarAxisRadial::setTickLengthIn(int inside) +{ + if (mTickLengthIn != inside) + { + mTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPPolarAxisRadial::setTickLengthOut(int outside) +{ + if (mTickLengthOut != outside) + { + mTickLengthOut = outside; + //mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPPolarAxisRadial::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + //mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPPolarAxisRadial::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPPolarAxisRadial::setSubTickLengthIn(int inside) +{ + if (mSubTickLengthIn != inside) + { + mSubTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPPolarAxisRadial::setSubTickLengthOut(int outside) +{ + if (mSubTickLengthOut != outside) + { + mSubTickLengthOut = outside; + //mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPPolarAxisRadial::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPPolarAxisRadial::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPPolarAxisRadial::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPPolarAxisRadial::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + //mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPPolarAxisRadial::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPPolarAxisRadial::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + //mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPPolarAxisRadial::setLabelPadding(int padding) +{ + if (mLabelPadding != padding) + { + mLabelPadding = padding; + //mCachedMarginValid = false; + } +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisRadial::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPPolarAxisRadial::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPPolarAxisRadial::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPPolarAxisRadial::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPPolarAxisRadial::rescale(bool onlyVisiblePlottables) +{ + Q_UNUSED(onlyVisiblePlottables) + /* TODO + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } + */ +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +void QCPPolarAxisRadial::pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const +{ + QCPVector2D posVector(pixelPos-mCenter); + radiusCoord = radiusToCoord(posVector.length()); + angleCoord = mAngularAxis->angleRadToCoord(posVector.angle()); +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +QPointF QCPPolarAxisRadial::coordToPixel(double angleCoord, double radiusCoord) const +{ + const double radiusPixel = coordToRadius(radiusCoord); + const double angleRad = mAngularAxis->coordToAngleRad(angleCoord); + return QPointF(mCenter.x()+qCos(angleRad)*radiusPixel, mCenter.y()+qSin(angleRad)*radiusPixel); +} + +double QCPPolarAxisRadial::coordToRadius(double coord) const +{ + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (coord-mRange.lower)/mRange.size()*mRadius; + else + return (mRange.upper-coord)/mRange.size()*mRadius; + } else // mScaleType == stLogarithmic + { + if (coord >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just return outside visible range + return !mRangeReversed ? mRadius+200 : mRadius-200; + else if (coord <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just return outside visible range + return !mRangeReversed ? mRadius-200 :mRadius+200; + else + { + if (!mRangeReversed) + return qLn(coord/mRange.lower)/qLn(mRange.upper/mRange.lower)*mRadius; + else + return qLn(mRange.upper/coord)/qLn(mRange.upper/mRange.lower)*mRadius; + } + } +} + +double QCPPolarAxisRadial::radiusToCoord(double radius) const +{ + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (radius)/mRadius*mRange.size()+mRange.lower; + else + return -(radius)/mRadius*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (radius)/mRadius)*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (-radius)/mRadius)*mRange.upper; + } +} + + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPPolarAxisRadial::SelectablePart QCPPolarAxisRadial::getPartAt(const QPointF &pos) const +{ + Q_UNUSED(pos) // TODO remove later + if (!mVisible) + return spNone; + + /* + TODO: + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else */ + return spNone; +} + +/* inherits documentation from base class */ +double QCPPolarAxisRadial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/* inherits documentation from base class */ +void QCPPolarAxisRadial::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPPolarAxisRadial::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis + (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref + QCPAxisRect::setRangeDragAxes) + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. +*/ +void QCPPolarAxisRadial::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + event->ignore(); + return; + } + + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + mDragStartRange = mRange; + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPPolarAxisRadial::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) // TODO remove later + Q_UNUSED(startPos) // TODO remove later + if (mDragging) + { + /* TODO + const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); + const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); + if (mScaleType == QCPPolarAxisRadial::stLinear) + { + const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); + setRange(mDragStartRange.lower+diff, mDragStartRange.upper+diff); + } else if (mScaleType == QCPPolarAxisRadial::stLogarithmic) + { + const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); + setRange(mDragStartRange.lower*diff, mDragStartRange.upper*diff); + } + */ + + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user drag individual axes + exclusively, by startig the drag on top of the axis. + + \seebaseclassmethod + + \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis + rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. + + \see QCPAxis::mousePressEvent +*/ +void QCPPolarAxisRadial::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + This mouse event reimplementation provides the functionality to let the user zoom individual axes + exclusively, by performing the wheel event on top of the axis. + + For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect + must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis + (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref + QCPAxisRect::setRangeZoomAxes) + + \seebaseclassmethod + + \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the + axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. +*/ +void QCPPolarAxisRadial::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + event->ignore(); + return; + } + + // TODO: + //const double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + //const double factor = qPow(mRangeZoomFactor, wheelSteps); + //scaleRange(factor, pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); + mParentPlot->replot(); +} + +void QCPPolarAxisRadial::updateGeometry(const QPointF ¢er, double radius) +{ + mCenter = center; + mRadius = radius; + if (mRadius < 1) mRadius = 1; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPPolarAxisRadial::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPPolarAxisRadial::draw(QCPPainter *painter) +{ + const double axisAngleRad = (mAngle+(mAngleReference==arAngularAxis ? mAngularAxis->angle() : 0))/180.0*M_PI; + const QPointF axisVector(qCos(axisAngleRad), qSin(axisAngleRad)); // semantically should be QCPVector2D, but we save time in loops when we keep it as QPointF + const QPointF tickNormal = QCPVector2D(axisVector).perpendicular().toPointF(); // semantically should be QCPVector2D, but we save time in loops when we keep it as QPointF + + // draw baseline: + painter->setPen(getBasePen()); + painter->drawLine(QLineF(mCenter, mCenter+axisVector*(mRadius-0.5))); + + // draw subticks: + if (!mSubTickVector.isEmpty()) + { + painter->setPen(getSubTickPen()); + for (int i=0; idrawLine(QLineF(tickPosition-tickNormal*mSubTickLengthIn, tickPosition+tickNormal*mSubTickLengthOut)); + } + } + + // draw ticks and labels: + if (!mTickVector.isEmpty()) + { + mLabelPainter.setAnchorReference(mCenter-axisVector); // subtract (normalized) axisVector, just to prevent degenerate tangents for tick label at exact lower axis range + mLabelPainter.setFont(getTickLabelFont()); + mLabelPainter.setColor(getTickLabelColor()); + const QPen ticksPen = getTickPen(); + painter->setPen(ticksPen); + for (int i=0; idrawLine(QLineF(tickPosition-tickNormal*mTickLengthIn, tickPosition+tickNormal*mTickLengthOut)); + // possibly draw tick labels: + if (!mTickVectorLabels.isEmpty()) + { + if ((!mRangeReversed && (i < mTickVectorLabels.count()-1 || mRadius-r > 10)) || + (mRangeReversed && (i > 0 || mRadius-r > 10))) // skip last label if it's closer than 10 pixels to angular axis + mLabelPainter.drawTickLabel(painter, tickPosition+tickNormal*mSubTickLengthOut, mTickVectorLabels.at(i)); + } + } + } +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPPolarAxisRadial::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels) || mRange.size() <= 0) return; + + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPPolarAxisRadial::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPPolarAxisRadial::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPPolarAxisRadial::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPPolarAxisRadial::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPPolarAxisRadial::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPPolarAxisRadial::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPPolarAxisRadial::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + + +/* inherits documentation from base class */ +QCP::Interaction QCPPolarAxisRadial::selectionCategory() const +{ + return QCP::iSelectAxes; +} +/* end of 'src/polar/radialaxis.cpp' */ + + +/* including file 'src/polar/layoutelement-angularaxis.cpp' */ +/* modified 2021-03-29T02:30:44, size 57266 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPolarAxisAngular +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPolarAxisAngular + \brief The main container for polar plots, representing the angular axis as a circle + + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and + functionality to be incomplete, as well as changing public interfaces in the future. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPPolarAxisAngular::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPPolarAxisAngular::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPPolarAxisAngular::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPPolarAxisAngular::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPPolarAxisAngular::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPPolarAxisAngular::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPPolarAxisAngular::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPPolarAxisAngular::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPPolarAxisAngular::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPPolarAxisAngular::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPPolarAxisAngular::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPPolarAxisAngular::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPPolarAxisAngular::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPPolarAxis instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPPolarAxisAngular::QCPPolarAxisAngular(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(false), + mRangeZoom(false), + mRangeZoomFactor(0.85), + // axis base: + mAngle(-90), + mAngleRad(mAngle/180.0*M_PI), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabelPadding(0), + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + //mTickLabelPadding(0), in label painter + mTickLabels(true), + //mTickLabelRotation(0), in label painter + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + mNumberMultiplyCross(false), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickLengthIn(5), + mTickLengthOut(0), + mSubTickLengthIn(2), + mSubTickLengthOut(0), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 360), + mRangeReversed(false), + // internal members: + mRadius(1), // non-zero initial value, will be overwritten in ::update() according to inner rect + mGrid(new QCPPolarGrid(this)), + mTicker(new QCPAxisTickerFixed), + mDragging(false), + mLabelPainter(parentPlot) +{ + // TODO: + //mInsetLayout->initializeParentPlot(mParentPlot); + //mInsetLayout->setParentLayerable(this); + //mInsetLayout->setParent(this); + + if (QCPAxisTickerFixed *fixedTicker = mTicker.dynamicCast().data()) + { + fixedTicker->setTickStep(30); + } + setAntialiased(true); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + setTickLabelPadding(5); + setTickLabelRotation(0); + setTickLabelMode(lmUpright); + mLabelPainter.setAnchorReferenceType(QCPLabelPainterPrivate::artNormal); + mLabelPainter.setAbbreviateDecimalPowers(false); + mLabelPainter.setCacheSize(24); // so we can cache up to 15-degree intervals, polar angular axis uses a bit larger cache than normal axes + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(30, 30, 30, 30)); + + addRadialAxis(); + mGrid->setRadialAxis(radialAxis()); +} + +QCPPolarAxisAngular::~QCPPolarAxisAngular() +{ + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order + mGrid = 0; + + delete mInsetLayout; + mInsetLayout = 0; + + QList radialAxesList = radialAxes(); + for (int i=0; i= 0 && index < mRadialAxes.size()) + { + return mRadialAxes.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPPolarAxisAngular::radialAxes() const +{ + return mRadialAxes; +} + + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPPolarAxisRadial *QCPPolarAxisAngular::addRadialAxis(QCPPolarAxisRadial *axis) +{ + QCPPolarAxisRadial *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPPolarAxisRadial(this); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->angularAxis() != this) + { + qDebug() << Q_FUNC_INFO << "passed radial axis doesn't have this angular axis as parent angular axis"; + return 0; + } + if (radialAxes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this angular axis"; + return 0; + } + } + mRadialAxes.append(newAxis); + return newAxis; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPPolarAxisAngular::removeRadialAxis(QCPPolarAxisRadial *radialAxis) +{ + if (mRadialAxes.contains(radialAxis)) + { + mRadialAxes.removeOne(radialAxis); + delete radialAxis; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "Radial axis isn't associated with this angular axis:" << reinterpret_cast(radialAxis); + return false; + } +} + +QRegion QCPPolarAxisAngular::exactClipRegion() const +{ + return QRegion(mCenter.x()-mRadius, mCenter.y()-mRadius, qRound(2*mRadius), qRound(2*mRadius), QRegion::Ellipse); +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPPolarAxisAngular::moveRange(double diff) +{ + QCPRange oldRange = mRange; + mRange.lower += diff; + mRange.upper += diff; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPPolarAxisAngular::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPPolarAxisAngular::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPPolarAxisAngular::rescale(bool onlyVisiblePlottables) +{ + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange range; + bool currentFoundRange; + if (mGraphs.at(i)->keyAxis() == this) + range = mGraphs.at(i)->getKeyRange(currentFoundRange, QCP::sdBoth); + else + range = mGraphs.at(i)->getValueRange(currentFoundRange, QCP::sdBoth); + if (currentFoundRange) + { + if (!haveRange) + newRange = range; + else + newRange.expand(range); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +void QCPPolarAxisAngular::pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const +{ + if (!mRadialAxes.isEmpty()) + mRadialAxes.first()->pixelToCoord(pixelPos, angleCoord, radiusCoord); + else + qDebug() << Q_FUNC_INFO << "no radial axis configured"; +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +QPointF QCPPolarAxisAngular::coordToPixel(double angleCoord, double radiusCoord) const +{ + if (!mRadialAxes.isEmpty()) + { + return mRadialAxes.first()->coordToPixel(angleCoord, radiusCoord); + } else + { + qDebug() << Q_FUNC_INFO << "no radial axis configured"; + return QPointF(); + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPPolarAxisAngular::SelectablePart QCPPolarAxisAngular::getPartAt(const QPointF &pos) const +{ + Q_UNUSED(pos) // TODO remove later + + if (!mVisible) + return spNone; + + /* + TODO: + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else */ + return spNone; +} + +/* inherits documentation from base class */ +double QCPPolarAxisAngular::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + /* + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; + */ + + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPPolarAxisAngular. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPPolarAxisAngular::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + setupTickVectors(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mCenter = mRect.center(); + mRadius = 0.5*qMin(qAbs(mRect.width()), qAbs(mRect.height())); + if (mRadius < 1) mRadius = 1; // prevent cases where radius might become 0 which causes trouble + for (int i=0; iupdateGeometry(mCenter, mRadius); + + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPPolarAxis doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPPolarAxisAngular::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +bool QCPPolarAxisAngular::removeGraph(QCPPolarGraph *graph) +{ + if (!mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph not in list:" << reinterpret_cast(graph); + return false; + } + + // remove plottable from legend: + graph->removeFromLegend(); + // remove plottable: + delete graph; + mGraphs.removeOne(graph); + return true; +} + +/* inherits documentation from base class */ +void QCPPolarAxisAngular::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/* inherits documentation from base class */ +void QCPPolarAxisAngular::draw(QCPPainter *painter) +{ + drawBackground(painter, mCenter, mRadius); + + // draw baseline circle: + painter->setPen(getBasePen()); + painter->drawEllipse(mCenter, mRadius, mRadius); + + // draw subticks: + if (!mSubTickVector.isEmpty()) + { + painter->setPen(getSubTickPen()); + for (int i=0; idrawLine(mCenter+mSubTickVectorCosSin.at(i)*(mRadius-mSubTickLengthIn), + mCenter+mSubTickVectorCosSin.at(i)*(mRadius+mSubTickLengthOut)); + } + } + + // draw ticks and labels: + if (!mTickVector.isEmpty()) + { + mLabelPainter.setAnchorReference(mCenter); + mLabelPainter.setFont(getTickLabelFont()); + mLabelPainter.setColor(getTickLabelColor()); + const QPen ticksPen = getTickPen(); + painter->setPen(ticksPen); + for (int i=0; idrawLine(mCenter+mTickVectorCosSin.at(i)*(mRadius-mTickLengthIn), outerTick); + // draw tick labels: + if (!mTickVectorLabels.isEmpty()) + { + if (i < mTickVectorLabels.count()-1 || (mTickVectorCosSin.at(i)-mTickVectorCosSin.first()).manhattanLength() > 5/180.0*M_PI) // skip last label if it's closer than approx 5 degrees to first + mLabelPainter.drawTickLabel(painter, outerTick, mTickVectorLabels.at(i)); + } + } + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPPolarAxisAngular::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPPolarAxisAngular::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPPolarAxisAngular::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPPolarAxisAngular::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPPolarAxisAngular::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPPolarAxisAngular::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +void QCPPolarAxisAngular::setRangeDrag(bool enabled) +{ + mRangeDrag = enabled; +} + +void QCPPolarAxisAngular::setRangeZoom(bool enabled) +{ + mRangeZoom = enabled; +} + +void QCPPolarAxisAngular::setRangeZoomFactor(double factor) +{ + mRangeZoomFactor = factor; +} + + + + + + + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPPolarAxisAngular::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + mRange = range.sanitizedForLinScale(); + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPPolarAxisAngular::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPPolarAxisAngular::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPPolarAxisAngular::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + mRange = mRange.sanitizedForLinScale(); + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPPolarAxisAngular::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPPolarAxisAngular::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange = mRange.sanitizedForLinScale(); + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPPolarAxisAngular::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + mRange = mRange.sanitizedForLinScale(); + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPPolarAxisAngular::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +void QCPPolarAxisAngular::setAngle(double degrees) +{ + mAngle = degrees; + mAngleRad = mAngle/180.0*M_PI; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPPolarAxisAngular::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPPolarAxisAngular::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + //mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPPolarAxisAngular::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + //mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPPolarAxisAngular::setTickLabelPadding(int padding) +{ + mLabelPainter.setPadding(padding); +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPPolarAxisAngular::setTickLabelFont(const QFont &font) +{ + mTickLabelFont = font; +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPPolarAxisAngular::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPPolarAxisAngular::setTickLabelRotation(double degrees) +{ + mLabelPainter.setRotation(degrees); +} + +void QCPPolarAxisAngular::setTickLabelMode(LabelMode mode) +{ + switch (mode) + { + case lmUpright: mLabelPainter.setAnchorMode(QCPLabelPainterPrivate::amSkewedUpright); break; + case lmRotated: mLabelPainter.setAnchorMode(QCPLabelPainterPrivate::amSkewedRotated); break; + } +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n If the first char was + 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. "5.5e9", which might be + visually unappealing in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPPolarAxisAngular::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + //mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mNumberMultiplyCross = false; + } else + { + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + mNumberBeautifulPowers = true; + else + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + + if (formatCode.length() < 3) + { + mNumberMultiplyCross = false; + } else + { + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + mNumberMultiplyCross = true; + else if (formatCode.at(2) == QLatin1Char('d')) + mNumberMultiplyCross = false; + else + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + } + } + mLabelPainter.setSubstituteExponent(mNumberBeautifulPowers); + mLabelPainter.setMultiplicationSymbol(mNumberMultiplyCross ? QCPLabelPainterPrivate::SymbolCross : QCPLabelPainterPrivate::SymbolDot); +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPPolarAxisAngular::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + //mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPPolarAxisAngular::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPPolarAxisAngular::setTickLengthIn(int inside) +{ + if (mTickLengthIn != inside) + { + mTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPPolarAxisAngular::setTickLengthOut(int outside) +{ + if (mTickLengthOut != outside) + { + mTickLengthOut = outside; + //mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPPolarAxisAngular::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + //mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPPolarAxisAngular::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPPolarAxisAngular::setSubTickLengthIn(int inside) +{ + if (mSubTickLengthIn != inside) + { + mSubTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPPolarAxisAngular::setSubTickLengthOut(int outside) +{ + if (mSubTickLengthOut != outside) + { + mSubTickLengthOut = outside; + //mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPPolarAxisAngular::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPPolarAxisAngular::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPPolarAxisAngular::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPPolarAxisAngular::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + //mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPPolarAxisAngular::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPPolarAxisAngular::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + //mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPPolarAxisAngular::setLabelPadding(int padding) +{ + if (mLabelPadding != padding) + { + mLabelPadding = padding; + //mCachedMarginValid = false; + } +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPPolarAxisAngular::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPPolarAxisAngular::drawBackground(QCPPainter *painter, const QPointF ¢er, double radius) +{ + // draw background fill (don't use circular clip, looks bad): + if (mBackgroundBrush != Qt::NoBrush) + { + QPainterPath ellipsePath; + ellipsePath.addEllipse(center, radius, radius); + painter->fillPath(ellipsePath, mBackgroundBrush); + } + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + QRegion clipCircle(center.x()-radius, center.y()-radius, qRound(2*radius), qRound(2*radius), QRegion::Ellipse); + QRegion originalClip = painter->clipRegion(); + painter->setClipRegion(clipCircle); + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + painter->setClipRegion(originalClip); + } +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPPolarAxisAngular::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + mSubTickVector.clear(); // since we might not pass it to mTicker->generate(), and we don't want old data in there + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); + + // fill cos/sin buffers which will be used by draw() and QCPPolarGrid::draw(), so we don't have to calculate it twice: + mTickVectorCosSin.resize(mTickVector.size()); + for (int i=0; ibuttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragAngularStart = range(); + mDragRadialStart.clear(); + for (int i=0; irange()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPPolarAxisAngular::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + bool doReplot = false; + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + if (mRangeDrag) + { + doReplot = true; + double angleCoordStart, radiusCoordStart; + double angleCoord, radiusCoord; + pixelToCoord(startPos, angleCoordStart, radiusCoordStart); + pixelToCoord(event->pos(), angleCoord, radiusCoord); + double diff = angleCoordStart - angleCoord; + setRange(mDragAngularStart.lower+diff, mDragAngularStart.upper+diff); + } + + for (int i=0; irangeDrag()) + continue; + doReplot = true; + double angleCoordStart, radiusCoordStart; + double angleCoord, radiusCoord; + ax->pixelToCoord(startPos, angleCoordStart, radiusCoordStart); + ax->pixelToCoord(event->pos(), angleCoord, radiusCoord); + if (ax->scaleType() == QCPPolarAxisRadial::stLinear) + { + double diff = radiusCoordStart - radiusCoord; + ax->setRange(mDragRadialStart.at(i).lower+diff, mDragRadialStart.at(i).upper+diff); + } else if (ax->scaleType() == QCPPolarAxisRadial::stLogarithmic) + { + if (radiusCoord != 0) + { + double diff = radiusCoordStart/radiusCoord; + ax->setRange(mDragRadialStart.at(i).lower*diff, mDragRadialStart.at(i).upper*diff); + } + } + } + + if (doReplot) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(QCustomPlot::rpQueuedReplot); + } + } +} + +/* inherits documentation from base class */ +void QCPPolarAxisAngular::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPPolarAxisAngular::wheelEvent(QWheelEvent *event) +{ + bool doReplot = false; + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + const double delta = event->delta(); +#else + const double delta = event->angleDelta().y(); +#endif + +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + const QPointF pos = event->pos(); +#else + const QPointF pos = event->position(); +#endif + const double wheelSteps = delta/120.0; // a single step delta is +/-120 usually + if (mRangeZoom) + { + double angleCoord, radiusCoord; + pixelToCoord(pos, angleCoord, radiusCoord); + scaleRange(qPow(mRangeZoomFactor, wheelSteps), angleCoord); + } + + for (int i=0; irangeZoom()) + continue; + doReplot = true; + double angleCoord, radiusCoord; + ax->pixelToCoord(pos, angleCoord, radiusCoord); + ax->scaleRange(qPow(ax->rangeZoomFactor(), wheelSteps), radiusCoord); + } + } + if (doReplot) + mParentPlot->replot(); +} + +bool QCPPolarAxisAngular::registerPolarGraph(QCPPolarGraph *graph) +{ + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "plottable already added:" << reinterpret_cast(graph); + return false; + } + if (graph->keyAxis() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this as axis:" << reinterpret_cast(graph); + return false; + } + + mGraphs.append(graph); + // possibly add plottable to legend: + if (mParentPlot->autoAddPlottableToLegend()) + graph->addToLegend(); + if (!graph->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + graph->setLayer(mParentPlot->currentLayer()); + return true; +} +/* end of 'src/polar/layoutelement-angularaxis.cpp' */ + + +/* including file 'src/polar/polargrid.cpp' */ +/* modified 2021-03-29T02:30:44, size 7493 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPolarGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPolarGrid + \brief The grid in both angular and radial dimensions for polar plots + + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and + functionality to be incomplete, as well as changing public interfaces in the future. +*/ + +/*! + Creates a QCPPolarGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every axis brings its own grid. +*/ +QCPPolarGrid::QCPPolarGrid(QCPPolarAxisAngular *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mType(gtNone), + mSubGridType(gtNone), + mAntialiasedSubGrid(true), + mAntialiasedZeroLine(true), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPPolarAxisAngular constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setType(gtAll); + setSubGridType(gtNone); + + setAngularPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setAngularSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + + setRadialPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setRadialSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setRadialZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + + setAntialiased(true); +} + +void QCPPolarGrid::setRadialAxis(QCPPolarAxisRadial *axis) +{ + mRadialAxis = axis; +} + +void QCPPolarGrid::setType(GridTypes type) +{ + mType = type; +} + +void QCPPolarGrid::setSubGridType(GridTypes type) +{ + mSubGridType = type; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPPolarGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPPolarGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPPolarGrid::setAngularPen(const QPen &pen) +{ + mAngularPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPPolarGrid::setAngularSubGridPen(const QPen &pen) +{ + mAngularSubGridPen = pen; +} + +void QCPPolarGrid::setRadialPen(const QPen &pen) +{ + mRadialPen = pen; +} + +void QCPPolarGrid::setRadialSubGridPen(const QPen &pen) +{ + mRadialSubGridPen = pen; +} + +void QCPPolarGrid::setRadialZeroLinePen(const QPen &pen) +{ + mRadialZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPPolarGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPPolarGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const QPointF center = mParentAxis->mCenter; + const double radius = mParentAxis->mRadius; + + painter->setBrush(Qt::NoBrush); + // draw main angular grid: + if (mType.testFlag(gtAngular)) + drawAngularGrid(painter, center, radius, mParentAxis->mTickVectorCosSin, mAngularPen); + // draw main radial grid: + if (mType.testFlag(gtRadial) && mRadialAxis) + drawRadialGrid(painter, center, mRadialAxis->tickVector(), mRadialPen, mRadialZeroLinePen); + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeGrid); + // draw sub angular grid: + if (mSubGridType.testFlag(gtAngular)) + drawAngularGrid(painter, center, radius, mParentAxis->mSubTickVectorCosSin, mAngularSubGridPen); + // draw sub radial grid: + if (mSubGridType.testFlag(gtRadial) && mRadialAxis) + drawRadialGrid(painter, center, mRadialAxis->subTickVector(), mRadialSubGridPen); +} + +void QCPPolarGrid::drawRadialGrid(QCPPainter *painter, const QPointF ¢er, const QVector &coords, const QPen &pen, const QPen &zeroPen) +{ + if (!mRadialAxis) return; + if (coords.isEmpty()) return; + const bool drawZeroLine = zeroPen != Qt::NoPen; + const double zeroLineEpsilon = qAbs(coords.last()-coords.first())*1e-6; + + painter->setPen(pen); + for (int i=0; icoordToRadius(coords.at(i)); + if (drawZeroLine && qAbs(coords.at(i)) < zeroLineEpsilon) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(zeroPen); + painter->drawEllipse(center, r, r); + painter->setPen(pen); + applyDefaultAntialiasingHint(painter); + } else + { + painter->drawEllipse(center, r, r); + } + } +} + +void QCPPolarGrid::drawAngularGrid(QCPPainter *painter, const QPointF ¢er, double radius, const QVector &ticksCosSin, const QPen &pen) +{ + if (ticksCosSin.isEmpty()) return; + + painter->setPen(pen); + for (int i=0; idrawLine(center, center+ticksCosSin.at(i)*radius); +} +/* end of 'src/polar/polargrid.cpp' */ + + +/* including file 'src/polar/polargraph.cpp' */ +/* modified 2021-03-29T02:30:44, size 44035 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPolarLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPolarLegendItem + \brief A legend item for polar plots + + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and + functionality to be incomplete, as well as changing public interfaces in the future. +*/ +QCPPolarLegendItem::QCPPolarLegendItem(QCPLegend *parent, QCPPolarGraph *graph) : + QCPAbstractLegendItem(parent), + mPolarGraph(graph) +{ + setAntialiased(false); +} + +void QCPPolarLegendItem::draw(QCPPainter *painter) +{ + if (!mPolarGraph) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPolarGraph->name()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPolarGraph->name()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPolarGraph->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +QSize QCPPolarLegendItem::minimumOuterSizeHint() const +{ + if (!mPolarGraph) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPolarGraph->name()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); + result.setHeight(qMax(textRect.height(), iconSize.height())); + result.rwidth() += mMargins.left()+mMargins.right(); + result.rheight() += mMargins.top()+mMargins.bottom(); + return result; +} + +QPen QCPPolarLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +QColor QCPPolarLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +QFont QCPPolarLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPolarGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPolarGraph + \brief A radial graph used to display data in polar plots + + \warning In this QCustomPlot version, polar plots are a tech preview. Expect documentation and + functionality to be incomplete, as well as changing public interfaces in the future. +*/ + +/* start of documentation of inline functions */ + +// TODO + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its angular and \a valueAxis as its radial axis. \a + keyAxis and \a valueAxis must reside in the same QCustomPlot, and the radial axis must be + associated with the angular axis. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPPolarGraph is automatically registered with the QCustomPlot instance inferred from + \a keyAxis. This QCustomPlot instance takes ownership of the QCPPolarGraph, so do not delete it + manually but use QCPPolarAxisAngular::removeGraph() instead. + + To directly create a QCPPolarGraph inside a plot, you shoud use the QCPPolarAxisAngular::addGraph + method. +*/ +QCPPolarGraph::QCPPolarGraph(QCPPolarAxisAngular *keyAxis, QCPPolarAxisRadial *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis), + mDataContainer(new QCPGraphDataContainer), + mName(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mPeriodic(true), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole) + //mSelectionDecorator(0) // TODO +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + + mKeyAxis->registerPolarGraph(this); + + //setSelectionDecorator(new QCPSelectionDecorator); // TODO + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + setLineStyle(lsLine); +} + +QCPPolarGraph::~QCPPolarGraph() +{ + /* TODO + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } + */ +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPPolarGraph::setName(const QString &name) +{ + mName = name; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPPolarGraph::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPPolarGraph::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPPolarGraph::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPPolarGraph::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +void QCPPolarGraph::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPPolarGraph::setKeyAxis(QCPPolarAxisAngular *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPPolarGraph::setValueAxis(QCPPolarAxisRadial *axis) +{ + mValueAxis = axis; +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPPolarGraph::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPPolarGraph::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPPolarGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp QCPPolarGraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp QCPPolarGraph-datasharing-2 + + \see addData +*/ +void QCPPolarGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPPolarGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPPolarGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPPolarGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +void QCPPolarGraph::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +void QCPPolarGraph::addData(double key, double value) +{ + mDataContainer->add(QCPGraphData(key, value)); +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +/* +void QCPPolarGraph::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + if (mSelectionDecorator) // delete old decorator if necessary + delete mSelectionDecorator; + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} +*/ + +void QCPPolarGraph::coordsToPixels(double key, double value, double &x, double &y) const +{ + if (mValueAxis) + { + const QPointF point = mValueAxis->coordToPixel(key, value); + x = point.x(); + y = point.y(); + } else + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + } +} + +const QPointF QCPPolarGraph::coordsToPixels(double key, double value) const +{ + if (mValueAxis) + { + return mValueAxis->coordToPixel(key, value); + } else + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + return QPointF(); + } +} + +void QCPPolarGraph::pixelsToCoords(double x, double y, double &key, double &value) const +{ + if (mValueAxis) + { + mValueAxis->pixelToCoord(QPointF(x, y), key, value); + } else + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + } +} + +void QCPPolarGraph::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + if (mValueAxis) + { + mValueAxis->pixelToCoord(pixelPos, key, value); + } else + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + } +} + +void QCPPolarGraph::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +void QCPPolarGraph::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, QCP::sdBoth); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } + keyAxis->setRange(newRange); + } +} + +void QCPPolarGraph::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); + QCPPolarAxisRadial *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPPolarAxisRadial::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPPolarAxisRadial::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +bool QCPPolarGraph::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + //if (!legend->hasItemWithPlottable(this)) // TODO + //{ + legend->addItem(new QCPPolarLegendItem(legend, this)); + return true; + //} else + // return false; +} + +bool QCPPolarGraph::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +bool QCPPolarGraph::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + + QCPPolarLegendItem *removableItem = 0; + for (int i=0; iitemCount(); ++i) // TODO: reduce this to code in QCPAbstractPlottable::removeFromLegend once unified + { + if (QCPPolarLegendItem *pli = qobject_cast(legend->item(i))) + { + if (pli->polarGraph() == this) + { + removableItem = pli; + break; + } + } + } + + if (removableItem) + return legend->removeItem(removableItem); + else + return false; +} + +bool QCPPolarGraph::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +double QCPPolarGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->rect().contains(pos.toPoint())) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPPolarGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPPolarGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +QRect QCPPolarGraph::clipRect() const +{ + if (mKeyAxis) + return mKeyAxis.data()->rect(); + else + return QRect(); +} + +void QCPPolarGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + painter->setClipRegion(mKeyAxis->exactClipRegion()); + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + //if (isSelectedSegment && mSelectionDecorator) + // mSelectionDecorator->applyBrush(painter); + //else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + + // draw line: + if (mLineStyle != lsNone) + { + //if (isSelectedSegment && mSelectionDecorator) + // mSelectionDecorator->applyPen(painter); + //else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + drawLinePlot(painter, lines); + } + + // draw scatters: + + QCPScatterStyle finalScatterStyle = mScatterStyle; + //if (isSelectedSegment && mSelectionDecorator) + // finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + //if (mSelectionDecorator) + // mSelectionDecorator->drawDecoration(painter, selection()); +} + +QCP::Interaction QCPPolarGraph::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +void QCPPolarGraph::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/* inherits documentation from base class */ +void QCPPolarGraph::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPPolarGraph::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, drawImpulsePlot, QCPAbstractPlottable1D::drawPolyline +*/ +void QCPPolarGraph::drawLinePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref + getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. + + In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), + this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to + operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN + segments of the two involved graphs, before passing the overlapping pairs to \ref + getChannelFillPolygon. + + Pass the points of this graph's line as \a lines, in pixel coordinates. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPPolarGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + applyFillAntialiasingHint(painter); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(*lines)); +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPPolarGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; ifillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +void QCPPolarGraph::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +void QCPPolarGraph::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +double QCPPolarGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = (std::numeric_limits::max)(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + getLines(&lineData, QCPDataRange(0, dataCount())); + QCPVector2D p(pixelPoint); + for (int i=0; isize(); +} + +void QCPPolarGraph::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +void QCPPolarGraph::drawPolyline(QCPPainter *painter, const QVector &lineData) const +{ + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } +} + +void QCPPolarGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); + QCPPolarAxisRadial *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + if (mPeriodic) + { + begin = mDataContainer->constBegin(); + end = mDataContainer->constEnd(); + } else + { + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + } + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPPolarGraph::getLines(QVector *lines, const QCPDataRange &dataRange) const +{ + if (!lines) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + switch (mLineStyle) + { + case lsNone: lines->clear(); break; + case lsLine: *lines = dataToLines(lineData); break; + } +} + +void QCPPolarGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); + QCPPolarAxisRadial *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (!scatters) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + + scatters->resize(data.size()); + for (int i=0; icoordToPixel(data.at(i).key, data.at(i).value); + } +} + +void QCPPolarGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + lineData->clear(); + + // TODO: fix for log axes and thick line style + + const QCPRange range = mValueAxis->range(); + bool reversed = mValueAxis->rangeReversed(); + const double clipMargin = range.size()*0.05; // extra distance from visible circle, so optimized outside lines can cover more angle before having to place a dummy point to prevent tangents + const double upperClipValue = range.upper + (reversed ? 0 : range.size()*0.05+clipMargin); // clip slightly outside of actual range to avoid line thicknesses to peek into visible circle + const double lowerClipValue = range.lower - (reversed ? range.size()*0.05+clipMargin : 0); // clip slightly outside of actual range to avoid line thicknesses to peek into visible circle + const double maxKeySkip = qAsin(qSqrt(clipMargin*(clipMargin+2*range.size()))/(range.size()+clipMargin))/M_PI*mKeyAxis->range().size(); // the maximum angle between two points on outer circle (r=clipValue+clipMargin) before connecting line becomes tangent to inner circle (r=clipValue) + double skipBegin = 0; + bool belowRange = false; + bool aboveRange = false; + QCPGraphDataContainer::const_iterator it = begin; + while (it != end) + { + if (it->value < lowerClipValue) + { + if (aboveRange) // jumped directly from above to below visible range, draw previous point so entry angle is correct + { + aboveRange = false; + if (!reversed) // TODO: with inner radius, we'll need else case here with projected border point + lineData->append(*(it-1)); + } + if (!belowRange) + { + skipBegin = it->key; + lineData->append(QCPGraphData(it->key, lowerClipValue)); + belowRange = true; + } + if (it->key-skipBegin > maxKeySkip) // add dummy point if we're exceeding the maximum skippable angle (to prevent unintentional intersections with visible circle) + { + skipBegin += maxKeySkip; + lineData->append(QCPGraphData(skipBegin, lowerClipValue)); + } + } else if (it->value > upperClipValue) + { + if (belowRange) // jumped directly from below to above visible range, draw previous point so entry angle is correct (if lower means outer, so if reversed axis) + { + belowRange = false; + if (reversed) + lineData->append(*(it-1)); + } + if (!aboveRange) + { + skipBegin = it->key; + lineData->append(QCPGraphData(it->key, upperClipValue)); + aboveRange = true; + } + if (it->key-skipBegin > maxKeySkip) // add dummy point if we're exceeding the maximum skippable angle (to prevent unintentional intersections with visible circle) + { + skipBegin += maxKeySkip; + lineData->append(QCPGraphData(skipBegin, upperClipValue)); + } + } else // value within bounds where we don't optimize away points + { + if (aboveRange) + { + aboveRange = false; + if (!reversed) + lineData->append(*(it-1)); // just entered from above, draw previous point so entry angle is correct (if above means outer, so if not reversed axis) + } + if (belowRange) + { + belowRange = false; + if (reversed) + lineData->append(*(it-1)); // just entered from below, draw previous point so entry angle is correct (if below means outer, so if reversed axis) + } + lineData->append(*it); // inside visible circle, add point normally + } + ++it; + } + // to make fill not erratic, add last point normally if it was outside visible circle: + if (aboveRange) + { + aboveRange = false; + if (!reversed) + lineData->append(*(it-1)); // just entered from above, draw previous point so entry angle is correct (if above means outer, so if not reversed axis) + } + if (belowRange) + { + belowRange = false; + if (reversed) + lineData->append(*(it-1)); // just entered from below, draw previous point so entry angle is correct (if below means outer, so if reversed axis) + } +} + +void QCPPolarGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + scatterData->clear(); + + const QCPRange range = mValueAxis->range(); + bool reversed = mValueAxis->rangeReversed(); + const double clipMargin = range.size()*0.05; + const double upperClipValue = range.upper + (reversed ? 0 : clipMargin); // clip slightly outside of actual range to avoid scatter size to peek into visible circle + const double lowerClipValue = range.lower - (reversed ? clipMargin : 0); // clip slightly outside of actual range to avoid scatter size to peek into visible circle + QCPGraphDataContainer::const_iterator it = begin; + while (it != end) + { + if (it->value > lowerClipValue && it->value < upperClipValue) + scatterData->append(*it); + ++it; + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPPolarGraph::dataToLines(const QVector &data) const +{ + QVector result; + QCPPolarAxisAngular *keyAxis = mKeyAxis.data(); + QCPPolarAxisRadial *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + // transform data points to pixels: + result.resize(data.size()); + for (int i=0; icoordToPixel(data.at(i).key, data.at(i).value); + return result; +} +/* end of 'src/polar/polargraph.cpp' */ + + diff --git a/ChaosDataPlayer/qcustomplot.h b/ChaosDataPlayer/qcustomplot.h new file mode 100644 index 0000000..8f0f78b --- /dev/null +++ b/ChaosDataPlayer/qcustomplot.h @@ -0,0 +1,7737 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2021 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 29.03.21 ** +** Version: 2.1.0 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include + +// some Qt version/configuration dependent macros to include or exclude certain code paths: +#ifdef QCUSTOMPLOT_USE_OPENGL +# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QCP_OPENGL_PBUFFER +# else +# define QCP_OPENGL_FBO +# endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) +# define QCP_OPENGL_OFFSCREENSURFACE +# endif +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +# define QCP_DEVICEPIXELRATIO_SUPPORTED +# if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +# define QCP_DEVICEPIXELRATIO_FLOAT +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef QCP_OPENGL_FBO +# include +# if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +# include +# else +# include +# include +# endif +# ifdef QCP_OPENGL_OFFSCREENSURFACE +# include +# else +# include +# endif +#endif +#ifdef QCP_OPENGL_PBUFFER +# include +#endif +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +# include +#else +# include +# include +# include +#endif +#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) +# include +#endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPPlottableInterface1D; +class QCPLegend; +class QCPItemPosition; +class QCPLayer; +class QCPAbstractLegendItem; +class QCPSelectionRect; +class QCPColorMap; +class QCPColorScale; +class QCPBars; +class QCPPolarAxisRadial; +class QCPPolarAxisAngular; +class QCPPolarGrid; +class QCPPolarGraph; + +/* including file 'src/global.h' */ +/* modified 2021-03-29T02:30:44, size 16981 */ + +#define QCUSTOMPLOT_VERSION_STR "2.1.0" +#define QCUSTOMPLOT_VERSION 0x020100 + +// decl definitions for shared library compilation/usage: +#if defined(QT_STATIC_BUILD) +# define QCP_LIB_DECL +#elif defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) +#ifndef Q_DECL_OVERRIDE +# define Q_DECL_OVERRIDE +#endif + +/*! + The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot + library. + + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. +*/ +#ifndef Q_MOC_RUN +namespace QCP { +#else +class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace + Q_GADGET + Q_ENUMS(ExportPen) + Q_ENUMS(ResolutionUnit) + Q_ENUMS(SignDomain) + Q_ENUMS(MarginSide) + Q_FLAGS(MarginSides) + Q_ENUMS(AntialiasedElement) + Q_FLAGS(AntialiasedElements) + Q_ENUMS(PlottingHint) + Q_FLAGS(PlottingHints) + Q_ENUMS(Interaction) + Q_FLAGS(Interactions) + Q_ENUMS(SelectionRectMode) + Q_ENUMS(SelectionType) +public: +#endif + +/*! + Defines the different units in which the image resolution can be specified in the export + functions. + + \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered +*/ +enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) + ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) + ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) + }; + +/*! + Defines how cosmetic pens (pens with numerical width 0) are handled during export. + + \see QCustomPlot::savePdf +*/ +enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting + ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) + }; + +/*! + Represents negative and positive sign domain, e.g. for passing to \ref + QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. + + This is primarily needed when working with logarithmic axis scales, since only one of the sign + domains can be visible at a time. +*/ +enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment + ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. + ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iNone = 0x000 ///< 0x000 None of the interactions are possible + ,iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) + ,iSelectPlottablesBeyondAxisRect = 0x100 ///< 0x100 When performing plottable selection/hit tests, this flag extends the sensitive area beyond the axis rect + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! + Defines the behaviour of the selection rect. + + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect +*/ +enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging + ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. + ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) + ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. + }; + +/*! + Defines the different ways a plottable can be selected. These images show the effect of the + different selection types, when the indicated selection rect was dragged: + +
+ + + + + + + + +
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
+
+ + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType +*/ +enum SelectionType { stNone ///< The plottable is not selectable + ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. + ,stSingleData ///< One individual data point can be selected at a time + ,stDataRange ///< Multiple contiguous data points (a data range) can be selected + ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected + }; + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + + +extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace + +} // end of namespace QCP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) +Q_DECLARE_METATYPE(QCP::ExportPen) +Q_DECLARE_METATYPE(QCP::ResolutionUnit) +Q_DECLARE_METATYPE(QCP::SignDomain) +Q_DECLARE_METATYPE(QCP::MarginSide) +Q_DECLARE_METATYPE(QCP::AntialiasedElement) +Q_DECLARE_METATYPE(QCP::PlottingHint) +Q_DECLARE_METATYPE(QCP::Interaction) +Q_DECLARE_METATYPE(QCP::SelectionRectMode) +Q_DECLARE_METATYPE(QCP::SelectionType) + +/* end of 'src/global.h' */ + + +/* including file 'src/vector2d.h' */ +/* modified 2021-03-29T02:30:44, size 4988 */ + +class QCP_LIB_DECL QCPVector2D +{ +public: + QCPVector2D(); + QCPVector2D(double x, double y); + QCPVector2D(const QPoint &point); + QCPVector2D(const QPointF &point); + + // getters: + double x() const { return mX; } + double y() const { return mY; } + double &rx() { return mX; } + double &ry() { return mY; } + + // setters: + void setX(double x) { mX = x; } + void setY(double y) { mY = y; } + + // non-virtual methods: + double length() const { return qSqrt(mX*mX+mY*mY); } + double lengthSquared() const { return mX*mX+mY*mY; } + double angle() const { return qAtan2(mY, mX); } + QPoint toPoint() const { return QPoint(int(mX), int(mY)); } + QPointF toPointF() const { return QPointF(mX, mY); } + + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } + void normalize(); + QCPVector2D normalized() const; + QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } + double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } + double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; + double distanceSquaredToLine(const QLineF &line) const; + double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; + + QCPVector2D &operator*=(double factor); + QCPVector2D &operator/=(double divisor); + QCPVector2D &operator+=(const QCPVector2D &vector); + QCPVector2D &operator-=(const QCPVector2D &vector); + +private: + // property members: + double mX, mY; + + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); + friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); + friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); + friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec); +}; +Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); + +inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } +inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } + +/*! \relates QCPVector2D + + Prints \a vec in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPVector2D &vec) +{ + d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; + return d.space(); +} + +/* end of 'src/vector2d.h' */ + + +/* including file 'src/painter.h' */ +/* modified 2021-03-29T02:30:44, size 4035 */ + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_ENUMS(PainterMode) + Q_FLAGS(PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + explicit QCPPainter(QPaintDevice *device); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) +Q_DECLARE_METATYPE(QCPPainter::PainterMode) + +/* end of 'src/painter.h' */ + + +/* including file 'src/paintbuffer.h' */ +/* modified 2021-03-29T02:30:44, size 5006 */ + +class QCP_LIB_DECL QCPAbstractPaintBuffer +{ +public: + explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); + virtual ~QCPAbstractPaintBuffer(); + + // getters: + QSize size() const { return mSize; } + bool invalidated() const { return mInvalidated; } + double devicePixelRatio() const { return mDevicePixelRatio; } + + // setters: + void setSize(const QSize &size); + void setInvalidated(bool invalidated=true); + void setDevicePixelRatio(double ratio); + + // introduced virtual methods: + virtual QCPPainter *startPainting() = 0; + virtual void donePainting() {} + virtual void draw(QCPPainter *painter) const = 0; + virtual void clear(const QColor &color) = 0; + +protected: + // property members: + QSize mSize; + double mDevicePixelRatio; + + // non-property members: + bool mInvalidated; + + // introduced virtual methods: + virtual void reallocateBuffer() = 0; +}; + + +class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); + virtual ~QCPPaintBufferPixmap() Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QPixmap mBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; + + +#ifdef QCP_OPENGL_PBUFFER +class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); + virtual ~QCPPaintBufferGlPbuffer() Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QGLPixelBuffer *mGlPBuffer; + int mMultisamples; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); + virtual ~QCPPaintBufferGlFbo() Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void donePainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QWeakPointer mGlContext; + QWeakPointer mGlPaintDevice; + QOpenGLFramebufferObject *mGlFrameBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_FBO + +/* end of 'src/paintbuffer.h' */ + + +/* including file 'src/layer.h' */ +/* modified 2021-03-29T02:30:44, size 7038 */ + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(LayerMode mode READ mode WRITE setMode) + /// \endcond +public: + + /*! + Defines the different rendering modes of a layer. Depending on the mode, certain layers can be + replotted individually, without the need to replot (possibly complex) layerables on other + layers. + + \see setMode + */ + enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. + ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). + }; + Q_ENUMS(LayerMode) + + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + virtual ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + LayerMode mode() const { return mMode; } + + // setters: + void setVisible(bool visible); + void setMode(LayerMode mode); + + // non-virtual methods: + void replot(); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + LayerMode mMode; + + // non-property members: + QWeakPointer mPaintBuffer; + + // non-virtual methods: + void draw(QCPPainter *painter); + void drawToPaintBuffer(); + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; +Q_DECLARE_METATYPE(QCPLayer::LayerMode) + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr); + virtual ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // selection events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // low-level mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPLayer; + friend class QCPAxisRect; +}; + +/* end of 'src/layer.h' */ + + +/* including file 'src/axis/range.h' */ +/* modified 2021-03-29T02:30:44, size 5280 */ + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const { return upper-lower; } + double center() const { return (upper+lower)*0.5; } + void normalize() { if (lower > upper) qSwap(lower, upper); } + void expand(const QCPRange &otherRange); + void expand(double includeCoord); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange expanded(double includeCoord) const; + QCPRange bounded(double lowerBound, double upperBound) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const { return value >= lower && value <= upper; } + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; + static const double maxRange; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/*! \relates QCPRange + + Prints \a range in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPRange &range) +{ + d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; + return d.space(); +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + +/* end of 'src/axis/range.h' */ + + +/* including file 'src/selection.h' */ +/* modified 2021-03-29T02:30:44, size 8569 */ + +class QCP_LIB_DECL QCPDataRange +{ +public: + QCPDataRange(); + QCPDataRange(int begin, int end); + + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } + bool operator!=(const QCPDataRange& other) const { return !(*this == other); } + + // getters: + int begin() const { return mBegin; } + int end() const { return mEnd; } + int size() const { return mEnd-mBegin; } + int length() const { return size(); } + + // setters: + void setBegin(int begin) { mBegin = begin; } + void setEnd(int end) { mEnd = end; } + + // non-property methods: + bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } + bool isEmpty() const { return length() == 0; } + QCPDataRange bounded(const QCPDataRange &other) const; + QCPDataRange expanded(const QCPDataRange &other) const; + QCPDataRange intersection(const QCPDataRange &other) const; + QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } + bool intersects(const QCPDataRange &other) const; + bool contains(const QCPDataRange &other) const; + +private: + // property members: + int mBegin, mEnd; + +}; +Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPDataSelection +{ +public: + explicit QCPDataSelection(); + explicit QCPDataSelection(const QCPDataRange &range); + + bool operator==(const QCPDataSelection& other) const; + bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } + QCPDataSelection &operator+=(const QCPDataSelection& other); + QCPDataSelection &operator+=(const QCPDataRange& other); + QCPDataSelection &operator-=(const QCPDataSelection& other); + QCPDataSelection &operator-=(const QCPDataRange& other); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); + + // getters: + int dataRangeCount() const { return mDataRanges.size(); } + int dataPointCount() const; + QCPDataRange dataRange(int index=0) const; + QList dataRanges() const { return mDataRanges; } + QCPDataRange span() const; + + // non-property methods: + void addDataRange(const QCPDataRange &dataRange, bool simplify=true); + void clear(); + bool isEmpty() const { return mDataRanges.isEmpty(); } + void simplify(); + void enforceType(QCP::SelectionType type); + bool contains(const QCPDataSelection &other) const; + QCPDataSelection intersection(const QCPDataRange &other) const; + QCPDataSelection intersection(const QCPDataSelection &other) const; + QCPDataSelection inverse(const QCPDataRange &outerRange) const; + +private: + // property members: + QList mDataRanges; + + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } +}; +Q_DECLARE_METATYPE(QCPDataSelection) + + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! \relates QCPDataRange + + Prints \a dataRange in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) +{ + d.nospace() << "QCPDataRange(" << dataRange.begin() << ", " << dataRange.end() << ")"; + return d; +} + +/*! \relates QCPDataSelection + + Prints \a selection in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) +{ + d.nospace() << "QCPDataSelection("; + for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // introduced virtual methods: + virtual int commonMargin(QCP::MarginSide side) const; + + // non-virtual methods: + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + /*! + Defines to which rect of a layout element the size constraints that can be set via \ref + setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the + margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect) + does not. + + \see setSizeConstraintRect + */ + enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect + , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins + }; + Q_ENUMS(SizeConstraintRect) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=nullptr); + virtual ~QCPLayoutElement() Q_DECL_OVERRIDE; + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setSizeConstraintRect(SizeConstraintRect constraintRect); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumOuterSizeHint() const; + virtual QSize maximumOuterSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + SizeConstraintRect mSizeConstraintRect; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + virtual void layoutChanged(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; +Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el); + static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el); + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) + Q_PROPERTY(int wrap READ wrap WRITE setWrap) + /// \endcond +public: + + /*! + Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). + The column/row at which wrapping into the next row/column occurs can be specified with \ref + setWrap. + + \see setFillOrder + */ + enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. + ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. + }; + Q_ENUMS(FillOrder) + + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid() Q_DECL_OVERRIDE; + + // getters: + int rowCount() const { return mElements.size(); } + int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + int wrap() const { return mWrap; } + FillOrder fillOrder() const { return mFillOrder; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + void setWrap(int count); + void setFillOrder(FillOrder order, bool rearrange=true); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool addElement(QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + int rowColToIndex(int row, int column) const; + void indexToRowCol(int index, int &row, int &column) const; + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + int mWrap; + FillOrder mFillOrder; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; +Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + Q_ENUMS(InsetPlacement) + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset() Q_DECL_OVERRIDE; + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; +Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) + +/* end of 'src/layout.h' */ + + +/* including file 'src/lineending.h' */ +/* modified 2021-03-29T02:30:44, size 4426 */ + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45 degrees rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + Q_ENUMS(EndingStyle) + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; + void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) + +/* end of 'src/lineending.h' */ + + +/* including file 'src/axis/labelpainter.h' */ +/* modified 2021-03-29T02:30:44, size 7086 */ + +class QCPLabelPainterPrivate +{ + Q_GADGET +public: + /*! + TODO + */ + enum AnchorMode { amRectangular ///< + ,amSkewedUpright ///< + ,amSkewedRotated ///< + }; + Q_ENUMS(AnchorMode) + + /*! + TODO + */ + enum AnchorReferenceType { artNormal ///< + ,artTangent ///< + }; + Q_ENUMS(AnchorReferenceType) + + /*! + TODO + */ + enum AnchorSide { asLeft ///< + ,asRight ///< + ,asTop ///< + ,asBottom ///< + ,asTopLeft + ,asTopRight + ,asBottomRight + ,asBottomLeft + }; + Q_ENUMS(AnchorSide) + + explicit QCPLabelPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPLabelPainterPrivate(); + + // setters: + void setAnchorSide(AnchorSide side); + void setAnchorMode(AnchorMode mode); + void setAnchorReference(const QPointF &pixelPoint); + void setAnchorReferenceType(AnchorReferenceType type); + void setFont(const QFont &font); + void setColor(const QColor &color); + void setPadding(int padding); + void setRotation(double rotation); + void setSubstituteExponent(bool enabled); + void setMultiplicationSymbol(QChar symbol); + void setAbbreviateDecimalPowers(bool enabled); + void setCacheSize(int labelCount); + + // getters: + AnchorMode anchorMode() const { return mAnchorMode; } + AnchorSide anchorSide() const { return mAnchorSide; } + QPointF anchorReference() const { return mAnchorReference; } + AnchorReferenceType anchorReferenceType() const { return mAnchorReferenceType; } + QFont font() const { return mFont; } + QColor color() const { return mColor; } + int padding() const { return mPadding; } + double rotation() const { return mRotation; } + bool substituteExponent() const { return mSubstituteExponent; } + QChar multiplicationSymbol() const { return mMultiplicationSymbol; } + bool abbreviateDecimalPowers() const { return mAbbreviateDecimalPowers; } + int cacheSize() const; + + //virtual int size() const; + + // non-property methods: + void drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text); + void clearCache(); + + // constants that may be used with setMultiplicationSymbol: + static const QChar SymbolDot; + static const QChar SymbolCross; + +protected: + struct CachedLabel + { + QPoint offset; + QPixmap pixmap; + }; + struct LabelData + { + AnchorSide side; + double rotation; // angle in degrees + QTransform transform; // the transform about the label anchor which is at (0, 0). Does not contain final absolute x/y positioning on the plot/axis + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds; + QRect totalBounds; // is in a coordinate system where label top left is at (0, 0) + QRect rotatedTotalBounds; // is in a coordinate system where the label anchor is at (0, 0) + QFont baseFont, expFont; + QColor color; + }; + + // property members: + AnchorMode mAnchorMode; + AnchorSide mAnchorSide; + QPointF mAnchorReference; + AnchorReferenceType mAnchorReferenceType; + QFont mFont; + QColor mColor; + int mPadding; + double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode + bool mSubstituteExponent; + QChar mMultiplicationSymbol; + bool mAbbreviateDecimalPowers; + // non-property members: + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + int mLetterCapHeight, mLetterDescent; + + // introduced virtual methods: + virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text); + virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters? + + // non-virtual methods: + QPointF getAnchorPos(const QPointF &tickPos); + void drawText(QCPPainter *painter, const QPointF &pos, const LabelData &labelData) const; + LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const; + void applyAnchorTransform(LabelData &labelData) const; + //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; + CachedLabel *createCachedLabel(const LabelData &labelData) const; + QByteArray cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const; + AnchorSide skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const; + AnchorSide rotationCorrectedSide(AnchorSide side, double rotation) const; + void analyzeFontMetrics(); +}; +Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorMode) +Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorSide) + + +/* end of 'src/axis/labelpainter.h' */ + + +/* including file 'src/axis/axisticker.h' */ +/* modified 2021-03-29T02:30:44, size 4230 */ + +class QCP_LIB_DECL QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the strategies that the axis ticker may follow when choosing the size of the tick step. + + \see setTickStepStrategy + */ + enum TickStepStrategy + { + tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) + ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count + }; + Q_ENUMS(TickStepStrategy) + + QCPAxisTicker(); + virtual ~QCPAxisTicker(); + + // getters: + TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } + int tickCount() const { return mTickCount; } + double tickOrigin() const { return mTickOrigin; } + + // setters: + void setTickStepStrategy(TickStepStrategy strategy); + void setTickCount(int count); + void setTickOrigin(double origin); + + // introduced virtual methods: + virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); + +protected: + // property members: + TickStepStrategy mTickStepStrategy; + int mTickCount; + double mTickOrigin; + + // introduced virtual methods: + virtual double getTickStep(const QCPRange &range); + virtual int getSubTickCount(double tickStep); + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); + virtual QVector createTickVector(double tickStep, const QCPRange &range); + virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); + virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); + + // non-virtual methods: + void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; + double pickClosest(double target, const QVector &candidates) const; + double getMantissa(double input, double *magnitude=nullptr) const; + double cleanMantissa(double input) const; + +private: + Q_DISABLE_COPY(QCPAxisTicker) + +}; +Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) +Q_DECLARE_METATYPE(QSharedPointer) + +/* end of 'src/axis/axisticker.h' */ + + +/* including file 'src/axis/axistickerdatetime.h' */ +/* modified 2021-03-29T02:30:44, size 3600 */ + +class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker +{ +public: + QCPAxisTickerDateTime(); + + // getters: + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + QTimeZone timeZone() const { return mTimeZone; } +#endif + + // setters: + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(Qt::TimeSpec spec); +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + void setTimeZone(const QTimeZone &zone); +# endif + void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) + void setTickOrigin(const QDateTime &origin); + + // static methods: + static QDateTime keyToDateTime(double key); + static double dateTimeToKey(const QDateTime &dateTime); + static double dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec=Qt::LocalTime); + +protected: + // property members: + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; +# if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + QTimeZone mTimeZone; +# endif + // non-property members: + enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerdatetime.h' */ + + +/* including file 'src/axis/axistickertime.h' */ +/* modified 2021-03-29T02:30:44, size 3542 */ + +class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the logical units in which fractions of time spans can be expressed. + + \see setFieldWidth, setTimeFormat + */ + enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) + ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) + ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) + ,tuHours ///< Hours (%%h in \ref setTimeFormat) + ,tuDays ///< Days (%%d in \ref setTimeFormat) + }; + Q_ENUMS(TimeUnit) + + QCPAxisTickerTime(); + + // getters: + QString timeFormat() const { return mTimeFormat; } + int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } + + // setters: + void setTimeFormat(const QString &format); + void setFieldWidth(TimeUnit unit, int width); + +protected: + // property members: + QString mTimeFormat; + QHash mFieldWidth; + + // non-property members: + TimeUnit mSmallestUnit, mBiggestUnit; + QHash mFormatPattern; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void replaceUnit(QString &text, TimeUnit unit, int value) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) + +/* end of 'src/axis/axistickertime.h' */ + + +/* including file 'src/axis/axistickerfixed.h' */ +/* modified 2021-03-29T02:30:44, size 3308 */ + +class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to + control the number of ticks in the axis range. + + \see setScaleStrategy + */ + enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. + ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. + ,ssPowers ///< An integer power of the specified tick step is allowed. + }; + Q_ENUMS(ScaleStrategy) + + QCPAxisTickerFixed(); + + // getters: + double tickStep() const { return mTickStep; } + ScaleStrategy scaleStrategy() const { return mScaleStrategy; } + + // setters: + void setTickStep(double step); + void setScaleStrategy(ScaleStrategy strategy); + +protected: + // property members: + double mTickStep; + ScaleStrategy mScaleStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; +}; +Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) + +/* end of 'src/axis/axistickerfixed.h' */ + + +/* including file 'src/axis/axistickertext.h' */ +/* modified 2021-03-29T02:30:44, size 3090 */ + +class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker +{ +public: + QCPAxisTickerText(); + + // getters: + QMap &ticks() { return mTicks; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setTicks(const QMap &ticks); + void setTicks(const QVector &positions, const QVector &labels); + void setSubTickCount(int subTicks); + + // non-virtual methods: + void clear(); + void addTick(double position, const QString &label); + void addTicks(const QMap &ticks); + void addTicks(const QVector &positions, const QVector &labels); + +protected: + // property members: + QMap mTicks; + int mSubTickCount; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickertext.h' */ + + +/* including file 'src/axis/axistickerpi.h' */ +/* modified 2021-03-29T02:30:44, size 3911 */ + +class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how fractions should be displayed in tick labels. + + \see setFractionStyle + */ + enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". + ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" + ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. + }; + Q_ENUMS(FractionStyle) + + QCPAxisTickerPi(); + + // getters: + QString piSymbol() const { return mPiSymbol; } + double piValue() const { return mPiValue; } + bool periodicity() const { return mPeriodicity; } + FractionStyle fractionStyle() const { return mFractionStyle; } + + // setters: + void setPiSymbol(QString symbol); + void setPiValue(double pi); + void setPeriodicity(int multiplesOfPi); + void setFractionStyle(FractionStyle style); + +protected: + // property members: + QString mPiSymbol; + double mPiValue; + int mPeriodicity; + FractionStyle mFractionStyle; + + // non-property members: + double mPiTickStep; // size of one tick step in units of mPiValue + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void simplifyFraction(int &numerator, int &denominator) const; + QString fractionToString(int numerator, int denominator) const; + QString unicodeFraction(int numerator, int denominator) const; + QString unicodeSuperscript(int number) const; + QString unicodeSubscript(int number) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) + +/* end of 'src/axis/axistickerpi.h' */ + + +/* including file 'src/axis/axistickerlog.h' */ +/* modified 2021-03-29T02:30:44, size 2594 */ + +class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker +{ +public: + QCPAxisTickerLog(); + + // getters: + double logBase() const { return mLogBase; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setLogBase(double base); + void setSubTickCount(int subTicks); + +protected: + // property members: + double mLogBase; + int mSubTickCount; + + // non-property members: + double mLogBaseLnInv; + + // reimplemented virtual methods: + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerlog.h' */ + + +/* including file 'src/axis/axis.h' */ +/* modified 2021-03-29T02:30:44, size 20913 */ + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + explicit QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(QVector tickVector READ tickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_ENUMS(AxisType) + Q_FLAGS(AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis() Q_DECL_OVERRIDE; + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + bool mSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + bool mDragging; + QCPRange mDragStartRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + + // introduced virtual methods: + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + // mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-virtual methods: + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::AxisType) +Q_DECLARE_METATYPE(QCPAxis::LabelSide) +Q_DECLARE_METATYPE(QCPAxis::ScaleType) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size(); + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + int offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + +/* end of 'src/axis/axis.h' */ + + +/* including file 'src/scatterstyle.h' */ +/* modified 2021-03-29T02:30:44, size 7275 */ + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Represents the various properties of a scatter style instance. For example, this enum is used + to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when + highlighting selected data points. + + Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref + setFromOther. + */ + enum ScatterProperty { spNone = 0x00 ///< 0x00 None + ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen + ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush + ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize + ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape + ,spAll = 0xFF ///< 0xFF All properties + }; + Q_ENUMS(ScatterProperty) + Q_FLAGS(ScatterProperties) + Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) + + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + Q_ENUMS(ScatterShape) + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void undefinePen(); + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, const QPointF &pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) + +/* end of 'src/scatterstyle.h' */ + + +/* including file 'src/datacontainer.h' */ +/* modified 2021-03-29T02:30:44, size 34070 */ + +/*! \relates QCPDataContainer + Returns whether the sort key of \a a is less than the sort key of \a b. + + \see QCPDataContainer::sort +*/ +template +inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } + +template +class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ +public: + typedef typename QVector::const_iterator const_iterator; + typedef typename QVector::iterator iterator; + + QCPDataContainer(); + + // getters: + int size() const { return mData.size()-mPreallocSize; } + bool isEmpty() const { return size() == 0; } + bool autoSqueeze() const { return mAutoSqueeze; } + + // setters: + void setAutoSqueeze(bool enabled); + + // non-virtual methods: + void set(const QCPDataContainer &data); + void set(const QVector &data, bool alreadySorted=false); + void add(const QCPDataContainer &data); + void add(const QVector &data, bool alreadySorted=false); + void add(const DataType &data); + void removeBefore(double sortKey); + void removeAfter(double sortKey); + void remove(double sortKeyFrom, double sortKeyTo); + void remove(double sortKey); + void clear(); + void sort(); + void squeeze(bool preAllocation=true, bool postAllocation=true); + + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } + const_iterator constEnd() const { return mData.constEnd(); } + iterator begin() { return mData.begin()+mPreallocSize; } + iterator end() { return mData.end(); } + const_iterator findBegin(double sortKey, bool expandedRange=true) const; + const_iterator findEnd(double sortKey, bool expandedRange=true) const; + const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } + QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); + QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); + QCPDataRange dataRange() const { return QCPDataRange(0, size()); } + void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; + +protected: + // property members: + bool mAutoSqueeze; + + // non-property memebers: + QVector mData; + int mPreallocSize; + int mPreallocIteration; + + // non-virtual methods: + void preallocateGrow(int minimumPreallocSize); + void performAutoSqueeze(); +}; + + + +// include implementation in header since it is a class template: +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataContainer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataContainer + \brief The generic data container for one-dimensional plottables + + This class template provides a fast container for data storage of one-dimensional data. The data + type is specified as template parameter (called \a DataType in the following) and must provide + some methods as described in the \ref qcpdatacontainer-datatype "next section". + + The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well + as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The + container uses a preallocation and a postallocation scheme, such that appending and prepending + data (with respect to the sort key) is very fast and minimizes reallocations. If data is added + which needs to be inserted between existing keys, the merge usually can be done quickly too, + using the fact that existing data is always sorted. The user can further improve performance by + specifying that added data is already itself sorted by key, if he can guarantee that this is the + case (see for example \ref add(const QVector &data, bool alreadySorted)). + + The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If + it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, + \ref end). Changing data members that are not the sort key (for most data types called \a key) is + safe from the container's perspective. + + Great care must be taken however if the sort key is modified through the non-const iterators. For + performance reasons, the iterators don't automatically cause a re-sorting upon their + manipulation. It is thus the responsibility of the user to leave the container in a sorted state + when finished with the data manipulation, before calling any other methods on the container. A + complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref + sort. Failing to do so can not be detected by the container efficiently and will cause both + rendering artifacts and potential data loss. + + Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually + done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which + introduces an according \a mDataContainer member and some convenience methods. + + \section qcpdatacontainer-datatype Requirements for the DataType template parameter + + The template parameter DataType is the type of the stored data points. It must be + trivially copyable and have the following public methods, preferably inline: + + \li double sortKey() const\n Returns the member variable of this data point that is the + sort key, defining the ordering in the container. Often this variable is simply called \a key. + + \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data + type initialized with its sort key set to \a sortKey. + + \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main + key (see method \c mainKey below). For most plottables this is the case. It is not the case for + example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason + why QCPCurve unlike QCPGraph can display parametric curves with loops. + + \li double mainKey() const\n Returns the variable of this data point considered the main + key. This is commonly the variable that is used as the coordinate of this data point on the key + axis of the plottable. This method is used for example when determining the automatic axis + rescaling of key axes (\ref QCPAxis::rescale). + + \li double mainValue() const\n Returns the variable of this data point considered the + main value. This is commonly the variable that is used as the coordinate of this data point on + the value axis of the plottable. + + \li QCPRange valueRange() const\n Returns the range this data point spans in the value + axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with + both lower and upper set to the main data point value. However if the data points can represent + multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close + values at each \a key) this method should return the range those values span. This method is used + for example when determining the automatic axis rescaling of value axes (\ref + QCPAxis::rescale). +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataContainer::size() const + + Returns the number of data points in the container. +*/ + +/*! \fn bool QCPDataContainer::isEmpty() const + + Returns whether this container holds no data points. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const + + Returns a const iterator to the first data point in this container. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const + + Returns a const iterator to the element past the last data point in this container. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const + + Returns a non-const iterator to the first data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const + + Returns a non-const iterator to the element past the last data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const + + Returns a const iterator to the element with the specified \a index. If \a index points beyond + the available elements in this container, returns \ref constEnd, i.e. an iterator past the last + valid element. + + You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref + dataselection-accessing "data selection page" for an example. +*/ + +/*! \fn QCPDataRange QCPDataContainer::dataRange() const + + Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the + begin index of the returned range is 0, and the end index is \ref size. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted + data +*/ +template +QCPDataContainer::QCPDataContainer() : + mAutoSqueeze(true), + mPreallocSize(0), + mPreallocIteration(0) +{ +} + +/*! + Sets whether the container automatically decides when to release memory from its post- and + preallocation pools when data points are removed. By default this is enabled and for typical + applications shouldn't be changed. + + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with + \ref squeeze. +*/ +template +void QCPDataContainer::setAutoSqueeze(bool enabled) +{ + if (mAutoSqueeze != enabled) + { + mAutoSqueeze = enabled; + if (mAutoSqueeze) + performAutoSqueeze(); + } +} + +/*! \overload + + Replaces the current data in this container with the provided \a data. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QCPDataContainer &data) +{ + clear(); + add(data); +} + +/*! \overload + + Replaces the current data in this container with the provided \a data + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QVector &data, bool alreadySorted) +{ + mData = data; + mPreallocSize = 0; + mPreallocIteration = 0; + if (!alreadySorted) + sort(); +} + +/*! \overload + + Adds the provided \a data to the current data in this container. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QCPDataContainer &data) +{ + if (data.isEmpty()) + return; + + const int n = data.size(); + const int oldSize = size(); + + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! + Adds the provided data points in \a data to the current data. + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QVector &data, bool alreadySorted) +{ + if (data.isEmpty()) + return; + if (isEmpty()) + { + set(data, alreadySorted); + return; + } + + const int n = data.size(); + const int oldSize = size(); + + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and then sort and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (!alreadySorted) // sort appended subrange if it wasn't already sorted + std::sort(end()-n, end(), qcpLessThanSortKey); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! \overload + + Adds the provided single data point to the current data. + + \see remove +*/ +template +void QCPDataContainer::add(const DataType &data) +{ + if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones + { + mData.append(data); + } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space + { + if (mPreallocSize < 1) + preallocateGrow(1); + --mPreallocSize; + *begin() = data; + } else // handle inserts, maintaining sorted keys + { + QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); + mData.insert(insertionPoint, data); + } +} + +/*! + Removes all data points with (sort-)keys smaller than or equal to \a sortKey. + + \see removeAfter, remove, clear +*/ +template +void QCPDataContainer::removeBefore(double sortKey) +{ + QCPDataContainer::iterator it = begin(); + QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + mPreallocSize += int(itEnd-it); // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys greater than or equal to \a sortKey. + + \see removeBefore, remove, clear +*/ +template +void QCPDataContainer::removeAfter(double sortKey) +{ + QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = end(); + mData.erase(it, itEnd); // typically adds it to the postallocated block + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a + sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single + data point with known (sort-)key, use \ref remove(double sortKey). + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) +{ + if (sortKeyFrom >= sortKeyTo || isEmpty()) + return; + + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); + mData.erase(it, itEnd); + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! \overload + + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) + precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small + fuzziness interval around the suspected position, depeding on the precision with which the + (sort-)key is known. + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKey) +{ + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (it != end() && it->sortKey() == sortKey) + { + if (it == begin()) + ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + else + mData.erase(it); + } + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points. + + \see remove, removeAfter, removeBefore +*/ +template +void QCPDataContainer::clear() +{ + mData.clear(); + mPreallocIteration = 0; + mPreallocSize = 0; +} + +/*! + Re-sorts all data points in the container by their sort key. + + When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, + \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full + resort is never necessary. However, if you choose to directly manipulate the sort key on data + points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it + is your responsibility to bring the container back into a sorted state before any other methods + are called on it. This can be achieved by calling this method immediately after finishing the + sort key manipulation. +*/ +template +void QCPDataContainer::sort() +{ + std::sort(begin(), end(), qcpLessThanSortKey); +} + +/*! + Frees all unused memory that is currently in the preallocation and postallocation pools. + + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref + setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical + applications. + + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation + should be freed, respectively. +*/ +template +void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) +{ + if (preAllocation) + { + if (mPreallocSize > 0) + { + std::copy(begin(), end(), mData.begin()); + mData.resize(size()); + mPreallocSize = 0; + } + mPreallocIteration = 0; + } + if (postAllocation) + mData.squeeze(); +} + +/*! + Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just + above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be + considered, otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is + returned. + + If the container is empty, returns \ref constEnd. + + \see findEnd, QCPPlottableInterface1D::findBegin +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty + --it; + return it; +} + +/*! + Returns an iterator to the element after the data point with a (sort-)key that is equal to, just + above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey + will be considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is + returned. + + If the container is empty, \ref constEnd is returned. + + \see findBegin, QCPPlottableInterface1D::findEnd +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constEnd()) + ++it; + return it; +} + +/*! + Returns the range encompassed by the (main-)key coordinate of all data points. The output + parameter \a foundRange indicates whether a sensible range was found. If this is false, you + should not use the returned QCPRange (e.g. the data container is empty or all points have the + same key). + + Use \a signDomain to control which sign of the key coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is + the case for most plottables, this method uses this fact and finds the range very quickly. + + \see valueRange +*/ +template +QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + double current; + + QCPDataContainer::const_iterator it = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (signDomain == QCP::sdBoth) // range may be anywhere + { + if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value + { + while (it != itEnd) // find first non-nan going up from left + { + if (!qIsNaN(it->mainValue())) + { + range.lower = it->mainKey(); + haveLower = true; + break; + } + ++it; + } + it = itEnd; + while (it != constBegin()) // find first non-nan going down from right + { + --it; + if (!qIsNaN(it->mainValue())) + { + range.upper = it->mainKey(); + haveUpper = true; + break; + } + } + } else // DataType is not sorted by main key, go through all data points and accordingly expand range + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Returns the range encompassed by the value coordinates of the data points in the specified key + range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The + output parameter \a foundRange indicates whether a sensible range was found. If this is false, + you should not use the returned QCPRange (e.g. the data container is empty or all points have the + same value). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Use \a signDomain to control which sign of the value coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + \see keyRange +*/ +template +QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPRange current; + QCPDataContainer::const_iterator itBegin = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (DataType::sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = findBegin(inKeyRange.lower, false); + itEnd = findEnd(inKeyRange.upper, false); + } + if (signDomain == QCP::sdBoth) // range may be anywhere + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Makes sure \a begin and \a end mark a data range that is both within the bounds of this data + container's data, as well as within the specified \a dataRange. The initial range described by + the passed iterators \a begin and \a end is never expanded, only contracted if necessary. + + This function doesn't require for \a dataRange to be within the bounds of this data container's + valid range. +*/ +template +void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const +{ + QCPDataRange iteratorRange(int(begin-constBegin()), int(end-constBegin())); + iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); + begin = constBegin()+iteratorRange.begin(); + end = constBegin()+iteratorRange.end(); +} + +/*! \internal + + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on + the preallocation history, the container will grow by more than requested, to speed up future + consecutive size increases. + + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this + method does nothing. +*/ +template +void QCPDataContainer::preallocateGrow(int minimumPreallocSize) +{ + if (minimumPreallocSize <= mPreallocSize) + return; + + int newPreallocSize = minimumPreallocSize; + newPreallocSize += (1u< +void QCPDataContainer::performAutoSqueeze() +{ + const int totalAlloc = mData.capacity(); + const int postAllocSize = totalAlloc-mData.size(); + const int usedSize = size(); + bool shrinkPostAllocation = false; + bool shrinkPreAllocation = false; + if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size + { + shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! + shrinkPreAllocation = mPreallocSize*10 > usedSize; + } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother + { + shrinkPostAllocation = postAllocSize > usedSize*5; + shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller + } + + if (shrinkPreAllocation || shrinkPostAllocation) + squeeze(shrinkPreAllocation, shrinkPostAllocation); +} + + +/* end of 'src/datacontainer.h' */ + + +/* including file 'src/plottable.h' */ +/* modified 2021-03-29T02:30:44, size 8461 */ + +class QCP_LIB_DECL QCPSelectionDecorator +{ + Q_GADGET +public: + QCPSelectionDecorator(); + virtual ~QCPSelectionDecorator(); + + // getters: + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } + + // setters: + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); + void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); + + // non-virtual methods: + void applyPen(QCPPainter *painter) const; + void applyBrush(QCPPainter *painter) const; + QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; + + // introduced virtual methods: + virtual void copyFrom(const QCPSelectionDecorator *other); + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mPen; + QBrush mBrush; + QCPScatterStyle mScatterStyle; + QCPScatterStyle::ScatterProperties mUsedScatterProperties; + // non-property members: + QCPAbstractPlottable *mPlottable; + + // introduced virtual methods: + virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); + +private: + Q_DISABLE_COPY(QCPSelectionDecorator) + friend class QCPAbstractPlottable; +}; +Q_DECLARE_METATYPE(QCPSelectionDecorator*) + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) + Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable() Q_DECL_OVERRIDE; + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + void setSelectionDecorator(QCPSelectionDecorator *decorator); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables + virtual QCPPlottableInterface1D *interface1D() { return nullptr; } + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; + + // non-property methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QString mName; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + QPointer mKeyAxis, mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + QCPSelectionDecorator *mSelectionDecorator; + + // reimplemented virtual methods: + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +/* end of 'src/plottable.h' */ + + +/* including file 'src/item.h' */ +/* modified 2021-03-29T02:30:44, size 9425 */ + +class QCP_LIB_DECL QCPItemAnchor +{ + Q_GADGET +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPosition() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return nullptr; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ + Q_GADGET +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + Q_ENUMS(PositionType) + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); + virtual ~QCPItemPosition() Q_DECL_OVERRIDE; + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &pos); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPosition(const QPointF &pixelPosition); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; +Q_DECLARE_METATYPE(QCPItemPosition::PositionType) + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem() Q_DECL_OVERRIDE; + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual QPointF anchorPixelPosition(int anchorId) const; + + // non-virtual methods: + double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +/* end of 'src/item.h' */ + + +/* including file 'src/core.h' */ +/* modified 2021-03-29T02:30:44, size 19304 */ + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot + ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. + ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. + ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. + }; + Q_ENUMS(RefreshPriority) + + explicit QCustomPlot(QWidget *parent = nullptr); + virtual ~QCustomPlot() Q_DECL_OVERRIDE; + + // getters: + QRect viewport() const { return mViewport; } + double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } + QCPSelectionRect *selectionRect() const { return mSelectionRect; } + bool openGl() const { return mOpenGl; } + + // setters: + void setViewport(const QRect &rect); + void setBufferDevicePixelRatio(double ratio); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + void setSelectionRectMode(QCP::SelectionRectMode mode); + void setSelectionRect(QCPSelectionRect *selectionRect); + void setOpenGl(bool enabled, int multisampling=16); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + template + PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=nullptr, QCPAxis *valueAxis=nullptr); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(); + int itemCount() const; + QList selectedItems() const; + template + ItemType *itemAt(const QPointF &pos, bool onlySelectable=false) const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + QCPAxisRect* axisRectAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); + double replotTime(bool average=false) const; + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterLayout(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + double mBufferDevicePixelRatio; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + QCP::SelectionRectMode mSelectionRectMode; + QCPSelectionRect *mSelectionRect; + bool mOpenGl; + + // non-property members: + QList > mPaintBuffers; + QPoint mMousePressPos; + bool mMouseHasMoved; + QPointer mMouseEventLayerable; + QPointer mMouseSignalLayerable; + QVariant mMouseEventLayerableDetails; + QVariant mMouseSignalLayerableDetails; + bool mReplotting; + bool mReplotQueued; + double mReplotTime, mReplotTimeAverage; + int mOpenGlMultisamples; + QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; + bool mOpenGlCacheLabelsBackup; +#ifdef QCP_OPENGL_FBO + QSharedPointer mGlContext; + QSharedPointer mGlSurface; + QSharedPointer mGlPaintDevice; +#endif + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void updateLayout(); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processPointSelection(QMouseEvent *event); + + // non-virtual methods: + bool registerPlottable(QCPAbstractPlottable *plottable); + bool registerGraph(QCPGraph *graph); + bool registerItem(QCPAbstractItem* item); + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=nullptr) const; + QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=nullptr) const; + void drawBackground(QCPPainter *painter); + void setupPaintBuffers(); + QCPAbstractPaintBuffer *createPaintBuffer(); + bool hasInvalidatedPaintBuffers(); + bool setupOpenGl(); + void freeOpenGl(); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; + friend class QCPAbstractPlottable; + friend class QCPGraph; + friend class QCPAbstractItem; +}; +Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) +Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) + + +// implementation of template functions: + +/*! + Returns the plottable at the pixel position \a pos. The plottable type (a QCPAbstractPlottable + subclass) that shall be taken into consideration can be specified via the template parameter. + + Plottables that only consist of single lines (like graphs) have a tolerance band around them, see + \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a + pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest + to \a pos. + + If there is no plottable of the specified type at \a pos, returns \c nullptr. + + \see itemAt, layoutElementAt +*/ +template +PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const +{ + PlottableType *resultPlottable = 0; + QVariant resultDetails; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + PlottableType *currentPlottable = qobject_cast(plottable); + if (!currentPlottable || (onlySelectable && !currentPlottable->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractPlottable::selectable + continue; + if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible + { + QVariant details; + double currentDistance = currentPlottable->selectTest(pos, false, dataIndex ? &details : nullptr); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = currentPlottable; + resultDetails = details; + resultDistance = currentDistance; + } + } + } + + if (resultPlottable && dataIndex) + { + QCPDataSelection sel = resultDetails.value(); + if (!sel.isEmpty()) + *dataIndex = sel.dataRange(0).begin(); + } + return resultPlottable; +} + +/*! + Returns the item at the pixel position \a pos. The item type (a QCPAbstractItem subclass) that shall be + taken into consideration can be specified via the template parameter. Items that only consist of single + lines (e.g. \ref QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, returns \c nullptr. + + \see plottableAt, layoutElementAt +*/ +template +ItemType *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + ItemType *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + ItemType *currentItem = qobject_cast(item); + if (!currentItem || (onlySelectable && !currentItem->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = currentItem->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = currentItem; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + + + +/* end of 'src/core.h' */ + + +/* including file 'src/plottable1d.h' */ +/* modified 2021-03-29T02:30:44, size 25638 */ + +class QCPPlottableInterface1D +{ +public: + virtual ~QCPPlottableInterface1D() = default; + // introduced pure virtual methods: + virtual int dataCount() const = 0; + virtual double dataMainKey(int index) const = 0; + virtual double dataSortKey(int index) const = 0; + virtual double dataMainValue(int index) const = 0; + virtual QCPRange dataValueRange(int index) const = 0; + virtual QPointF dataPixelPosition(int index) const = 0; + virtual bool sortKeyIsMainKey() const = 0; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; + virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; +}; + +template +class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below) +{ + // No Q_OBJECT macro due to template class + +public: + QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable1D() Q_DECL_OVERRIDE; + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer > mDataContainer; + + // helpers for subclasses: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable1D) + +}; + + + +// include implementation in header since it is a class template: +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableInterface1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableInterface1D + \brief Defines an abstract interface for one-dimensional plottables + + This class contains only pure virtual methods which define a common interface to the data + of one-dimensional plottables. + + For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred + base class for one-dimensional plottables). So if you use that template class as base class of + your one-dimensional plottable, you won't have to care about implementing the 1d interface + yourself. + + If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d + interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref + QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure + virtual methods of the 1d interface, matching your data container. Also, reimplement \ref + QCPAbstractPlottable::interface1D to return the \c this pointer. + + If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this + interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return + value. If it indeed implements this interface, you may use it to access the plottable's data + without needing to know the exact type of the plottable or its data point type. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; + + Returns the number of data points of the plottable. +*/ + +/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + + Returns a data selection containing all the data points of this plottable which are contained (or + hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref + dataselection "data selection mechanism"). + + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not + selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). + + \note \a rect must be a normalized rect (positive or zero width and height). This is especially + important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily + normalized. Use QRect::normalized() when passing a rect which might not be normalized. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 + + Returns the main key of the data point at the given \a index. + + What the main key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 + + Returns the sort key of the data point at the given \a index. + + What the sort key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 + + Returns the main value of the data point at the given \a index. + + What the main value is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 + + Returns the value range of the data point at the given \a index. + + What the value range is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 + + Returns the pixel position on the widget surface at which the data point at the given \a index + appears. + + Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel + coordinates. However, depending on the plottable, this might be a different apparent position + than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data + values can be shifted depending on their stacking, bar grouping or configured base value. +*/ + +/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 + + Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). + + What the sort and main keys are, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 + + Returns the index of the data point with a (sort-)key that is equal to, just below, or just above + \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, + otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. + + If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop + using these methods will not iterate over the index 0). + + \see findEnd, QCPDataContainer::findBegin +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 + + Returns the index one after the data point with a (sort-)key that is equal to, just above, or + just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be + considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, the index just above the + highest data point is returned. + + If the container is empty, returns 0. + + \see findBegin, QCPDataContainer::findEnd +*/ + +/* end documentation of pure virtual functions */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable1D + \brief A template base class for plottables with one-dimensional data + + This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref + QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with + one key dimension), such as \ref QCPGraph and QCPCurve. + + The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref + QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member + \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and + implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most + subclassed plottables don't need to worry about this anymore. + + Further, it provides a convenience method for retrieving selected/unselected data segments via + \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to + draw selected segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref + QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data + interface. In spite of that, most plottable subclasses will want to reimplement those methods + again, to provide a more accurate hit test based on their specific data visualization geometry. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() + + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D + interface. + + \seebaseclassmethod +*/ + +/* end documentation of inline functions */ + +/*! + Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable + "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. +*/ +template +QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QCPDataContainer) +{ +} + +template +QCPAbstractPlottable1D::~QCPAbstractPlottable1D() +{ +} + +/*! + \copydoc QCPPlottableInterface1D::dataCount +*/ +template +int QCPAbstractPlottable1D::dataCount() const +{ + return mDataContainer->size(); +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainKey +*/ +template +double QCPAbstractPlottable1D::dataMainKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataSortKey +*/ +template +double QCPAbstractPlottable1D::dataSortKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->sortKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainValue +*/ +template +double QCPAbstractPlottable1D::dataMainValue(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainValue(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataValueRange +*/ +template +QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->valueRange(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QCPRange(0, 0); + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataPixelPosition +*/ +template +QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + return coordsToPixels(it->mainKey(), it->mainValue()); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/*! + \copydoc QCPPlottableInterface1D::sortKeyIsMainKey +*/ +template +bool QCPAbstractPlottable1D::sortKeyIsMainKey() const +{ + return DataType::sortKeyIsMainKey(); +} + +/*! + Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + // convert rect given in pixels to ranges given in plot coordinates: + double key1, value1, key2, value2; + pixelsToCoords(rect.topLeft(), key1, value1); + pixelsToCoords(rect.bottomRight(), key2, value2); + QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 + QCPRange valueRange(value1, value2); + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + begin = mDataContainer->findBegin(keyRange.lower, false); + end = mDataContainer->findEnd(keyRange.upper, false); + } + if (begin == end) + return result; + + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (currentSegmentBegin == -1) + { + if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment + currentSegmentBegin = int(it-mDataContainer->constBegin()); + } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended + { + result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false); + currentSegmentBegin = -1; + } + } + // process potential last segment: + if (currentSegmentBegin != -1) + result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false); + + result.simplify(); + return result; +} + +/*! + \copydoc QCPPlottableInterface1D::findBegin +*/ +template +int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const +{ + return int(mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin()); +} + +/*! + \copydoc QCPPlottableInterface1D::findEnd +*/ +template +int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const +{ + return int(mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin()); +} + +/*! + Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point + to \a pos. + + \seebaseclassmethod +*/ +template +double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + QCPDataSelection selectionResult; + double minDistSqr = (std::numeric_limits::max)(); + int minDistIndex = mDataContainer->size(); + + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + begin = mDataContainer->findBegin(posKeyMin, true); + end = mDataContainer->findEnd(posKeyMax, true); + } + if (begin == end) + return -1; + QCPRange keyRange(mKeyAxis->range()); + QCPRange valueRange(mValueAxis->range()); + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double mainKey = it->mainKey(); + const double mainValue = it->mainValue(); + if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points + { + const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + minDistIndex = int(it-mDataContainer->constBegin()); + } + } + } + if (minDistIndex != mDataContainer->size()) + selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); + + selectionResult.simplify(); + if (details) + details->setValue(selectionResult); + return qSqrt(minDistSqr); +} + +/*! + Splits all data into selected and unselected segments and outputs them via \a selectedSegments + and \a unselectedSegments, respectively. + + This is useful when subclasses implement their \ref draw method and need to draw selected + segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + \see setSelection +*/ +template +void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! + A helper method which draws a line with the passed \a painter, according to the pixel data in \a + lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is + the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or + crashing). + + Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c + QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter + style allows. +*/ +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData) const +{ + // if drawing lines in plot (instead of PDF), reduce 1px lines to cosmetic, because at least in + // Qt6 drawing of "1px" width lines is much slower even though it has same appearance apart from + // High-DPI. In High-DPI cases people must set a pen width slightly larger than 1.0 to get + // correct DPI scaling of width, but of course with performance penalty. + if (!painter->modes().testFlag(QCPPainter::pmVectorized) && + qFuzzyCompare(painter->pen().widthF(), 1.0)) + { + QPen newPen = painter->pen(); + newPen.setWidth(0); + painter->setPen(newPen); + } + + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } +} + + +/* end of 'src/plottable1d.h' */ + + +/* including file 'src/colorgradient.h' */ +/* modified 2021-03-29T02:30:44, size 7262 */ + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines how NaN data points shall appear in the plot. + + \see setNanHandling, setNanColor + */ + enum NanHandling { nhNone ///< NaN data points are not explicitly handled and shouldn't occur in the data (this gives slight performance improvement) + ,nhLowestColor ///< NaN data points appear as the lowest color defined in this QCPColorGradient + ,nhHighestColor ///< NaN data points appear as the highest color defined in this QCPColorGradient + ,nhTransparent ///< NaN data points appear transparent + ,nhNanColor ///< NaN data points appear as the color defined with \ref setNanColor + }; + Q_ENUMS(NanHandling) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(); + QCPColorGradient(GradientPreset preset); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + NanHandling nanHandling() const { return mNanHandling; } + QColor nanColor() const { return mNanColor; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setNanHandling(NanHandling handling); + void setNanColor(const QColor &color); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + NanHandling mNanHandling; + QColor mNanColor; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) + bool mColorBufferInvalidated; + + // non-virtual methods: + bool stopsUseAlpha() const; + void updateColorBuffer(); +}; +Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) +Q_DECLARE_METATYPE(QCPColorGradient::NanHandling) +Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) + +/* end of 'src/colorgradient.h' */ + + +/* including file 'src/selectiondecorator-bracket.h' */ +/* modified 2021-03-29T02:30:44, size 4458 */ + +class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator +{ + Q_GADGET +public: + + /*! + Defines which shape is drawn at the boundaries of selected data ranges. + + Some of the bracket styles further allow specifying a height and/or width, see \ref + setBracketHeight and \ref setBracketWidth. + */ + enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. + ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsPlus ///< A plus is drawn. + ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. + }; + Q_ENUMS(BracketStyle) + + QCPSelectionDecoratorBracket(); + virtual ~QCPSelectionDecoratorBracket() Q_DECL_OVERRIDE; + + // getters: + QPen bracketPen() const { return mBracketPen; } + QBrush bracketBrush() const { return mBracketBrush; } + int bracketWidth() const { return mBracketWidth; } + int bracketHeight() const { return mBracketHeight; } + BracketStyle bracketStyle() const { return mBracketStyle; } + bool tangentToData() const { return mTangentToData; } + int tangentAverage() const { return mTangentAverage; } + + // setters: + void setBracketPen(const QPen &pen); + void setBracketBrush(const QBrush &brush); + void setBracketWidth(int width); + void setBracketHeight(int height); + void setBracketStyle(BracketStyle style); + void setTangentToData(bool enabled); + void setTangentAverage(int pointCount); + + // introduced virtual methods: + virtual void drawBracket(QCPPainter *painter, int direction) const; + + // virtual methods: + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; + +protected: + // property members: + QPen mBracketPen; + QBrush mBracketBrush; + int mBracketWidth; + int mBracketHeight; + BracketStyle mBracketStyle; + bool mTangentToData; + int mTangentAverage; + + // non-virtual methods: + double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; + QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; + +}; +Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) + +/* end of 'src/selectiondecorator-bracket.h' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.h' */ +/* modified 2021-03-29T02:30:44, size 7529 */ + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect() Q_DECL_OVERRIDE; + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + QList rangeDragAxes(Qt::Orientation orientation); + QList rangeZoomAxes(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeDragAxes(QList axes); + void setRangeDragAxes(QList horizontal, QList vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QList axes); + void setRangeZoomAxes(QList horizontal, QList vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=nullptr); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void zoom(const QRectF &pixelRect); + void zoom(const QRectF &pixelRect, const QList &affectedAxes); + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QList > mRangeDragHorzAxis, mRangeDragVertAxis; + QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + + // non-property members: + QList mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + bool mDragging; + QHash > mAxes; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; + virtual void layoutChanged() Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +/* end of 'src/layoutelements/layoutelement-axisrect.h' */ + + +/* including file 'src/layoutelements/layoutelement-legend.h' */ +/* modified 2021-03-29T02:30:44, size 10425 */ + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend() Q_DECL_OVERRIDE; + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + +/* end of 'src/layoutelements/layoutelement-legend.h' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.h' */ +/* modified 2021-03-29T02:30:44, size 5359 */ + +class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPTextElement(QCustomPlot *parentPlot); + QCPTextElement(QCustomPlot *parentPlot, const QString &text); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); + + // getters: + QString text() const { return mText; } + int textFlags() const { return mTextFlags; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setTextFlags(int flags); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + void clicked(QMouseEvent *event); + void doubleClicked(QMouseEvent *event); + +protected: + // property members: + QString mText; + int mTextFlags; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPTextElement) +}; + + + +/* end of 'src/layoutelements/layoutelement-textelement.h' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.h' */ +/* modified 2021-03-29T02:30:44, size 5939 */ + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale() Q_DECL_OVERRIDE; + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/* end of 'src/layoutelements/layoutelement-colorscale.h' */ + + +/* including file 'src/plottables/plottable-graph.h' */ +/* modified 2021-03-29T02:30:44, size 9316 */ + +class QCP_LIB_DECL QCPGraphData +{ +public: + QCPGraphData(); + QCPGraphData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPGraphDataContainer + + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPGraph holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPGraphData, QCPGraph::setData +*/ +typedef QCPDataContainer QCPGraphDataContainer; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph() Q_DECL_OVERRIDE; + + // getters: + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + int mScatterSkip; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; + virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; + + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + QVector dataToLines(const QVector &data) const; + QVector dataToStepLeftLines(const QVector &data) const; + QVector dataToStepRightLines(const QVector &data) const; + QVector dataToStepCenterLines(const QVector &data) const; + QVector dataToImpulseLines(const QVector &data) const; + QVector getNonNanSegments(const QVector *lineData, Qt::Orientation keyOrientation) const; + QVector > getOverlappingSegments(QVector thisSegments, const QVector *thisData, QVector otherSegments, const QVector *otherData) const; + bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const; + QPointF getFillBasePoint(QPointF matchingDataPoint) const; + const QPolygonF getFillPolygon(const QVector *lineData, QCPDataRange segment) const; + const QPolygonF getChannelFillPolygon(const QVector *thisData, QCPDataRange thisSegment, const QVector *otherData, QCPDataRange otherSegment) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPGraph::LineStyle) + +/* end of 'src/plottables/plottable-graph.h' */ + + +/* including file 'src/plottables/plottable-curve.h' */ +/* modified 2021-03-29T02:30:44, size 7434 */ + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + + inline double sortKey() const { return t; } + inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return false; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPCurveDataContainer + + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a + sortKey() (returning \a t) is different from \a mainKey() (returning \a key). + + This template instantiation is the container in which QCPCurve holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPCurveData, QCPCurve::setData +*/ +typedef QCPDataContainer QCPCurveDataContainer; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + Q_ENUMS(LineStyle) + + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve() Q_DECL_OVERRIDE; + + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void setData(const QVector &keys, const QVector &values); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(const QVector &keys, const QVector &values); + void addData(double t, double key, double value); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPScatterStyle mScatterStyle; + int mScatterSkip; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; + + // non-virtual methods: + void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; + int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QPointF getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPCurve::LineStyle) + +/* end of 'src/plottables/plottable-curve.h' */ + + +/* including file 'src/plottables/plottable-bars.h' */ +/* modified 2021-03-29T02:30:44, size 8955 */ + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(SpacingType) + + explicit QCPBarsGroup(QCustomPlot *parentPlot); + virtual ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; +Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) + + +class QCP_LIB_DECL QCPBarsData +{ +public: + QCPBarsData(); + QCPBarsData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPBarsDataContainer + + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPBars holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPBarsData, QCPBars::setData +*/ +typedef QCPDataContainer QCPBarsDataContainer; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars() Q_DECL_OVERRIDE; + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + double stackingGap() const { return mStackingGap; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QSharedPointer data() const { return mDataContainer; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setStackingGap(double pixels); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + double mStackingGap; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; + QRectF getBarRect(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; +Q_DECLARE_METATYPE(QCPBars::WidthType) + +/* end of 'src/plottables/plottable-bars.h' */ + + +/* including file 'src/plottables/plottable-statisticalbox.h' */ +/* modified 2021-03-29T02:30:44, size 7522 */ + +class QCP_LIB_DECL QCPStatisticalBoxData +{ +public: + QCPStatisticalBoxData(); + QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); + + inline double sortKey() const { return key; } + inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return median; } + + inline QCPRange valueRange() const + { + QCPRange result(minimum, maximum); + for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) + result.expand(*it); + return result; + } + + double key, minimum, lowerQuartile, median, upperQuartile, maximum; + QVector outliers; +}; +Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); + + +/*! \typedef QCPStatisticalBoxDataContainer + + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPStatisticalBox holds its data. For + details about the generic container, see the documentation of the class template \ref + QCPDataContainer. + + \see QCPStatisticalBoxData, QCPStatisticalBox::setData +*/ +typedef QCPDataContainer QCPStatisticalBoxDataContainer; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QSharedPointer data() const { return mDataContainer; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + bool whiskerAntialiased() const { return mWhiskerAntialiased; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setWhiskerAntialiased(bool enabled); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen; + bool mWhiskerAntialiased; + QPen mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; + QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-statisticalbox.h' */ + + +/* including file 'src/plottables/plottable-colormap.h' */ +/* modified 2021-03-29T02:30:44, size 7092 */ + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + unsigned char alpha(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void clearAlpha(); + void fill(double z); + void fillAlpha(unsigned char alpha); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + + // non-property members: + double *mData; + unsigned char *mAlpha; + QCPRange mDataBounds; + bool mDataModified; + + bool createAlpha(bool initializeOpaque=true); + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap() Q_DECL_OVERRIDE; + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-colormap.h' */ + + +/* including file 'src/plottables/plottable-financial.h' */ +/* modified 2021-03-29T02:30:44, size 8644 */ + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + + inline double sortKey() const { return key; } + inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return open; } + + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them + + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPFinancialDataContainer + + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPFinancial holds its data. For details + about the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPFinancialData, QCPFinancial::setData +*/ +typedef QCPDataContainer QCPFinancialDataContainer; + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the ways the width of the financial bar can be specified. Thus it defines what the + number passed to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< width is in absolute pixels + ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size + ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial() Q_DECL_OVERRIDE; + + // getters: + QSharedPointer data() const { return mDataContainer; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void addData(double key, double open, double high, double low, double close); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // static methods: + static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + ChartStyle mChartStyle; + double mWidth; + WidthType mWidthType; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + double getPixelWidth(double key, double keyPixel) const; + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; + QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) + +/* end of 'src/plottables/plottable-financial.h' */ + + +/* including file 'src/plottables/plottable-errorbar.h' */ +/* modified 2021-03-29T02:30:44, size 7749 */ + +class QCP_LIB_DECL QCPErrorBarsData +{ +public: + QCPErrorBarsData(); + explicit QCPErrorBarsData(double error); + QCPErrorBarsData(double errorMinus, double errorPlus); + + double errorMinus, errorPlus; +}; +Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPErrorBarsDataContainer + + Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref + QCPErrorBarsData>. + + This is the container in which \ref QCPErrorBars holds its data. Unlike most other data + containers for plottables, it is not based on \ref QCPDataContainer. This is because the error + bars plottable is special in that it doesn't store its own key and value coordinate per error + bar. It adopts the key and value from the plottable to which the error bars shall be applied + (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a + sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices + of the other plottable's data. + + \see QCPErrorBarsData, QCPErrorBars::setData +*/ +typedef QVector QCPErrorBarsDataContainer; + +class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QSharedPointer data READ data WRITE setData) + Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) + /// \endcond +public: + + /*! + Defines in which orientation the error bars shall appear. If your data needs both error + dimensions, create two \ref QCPErrorBars with different \ref ErrorType. + + \see setErrorType + */ + enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) + ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) + }; + Q_ENUMS(ErrorType) + + explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPErrorBars() Q_DECL_OVERRIDE; + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } + ErrorType errorType() const { return mErrorType; } + double whiskerWidth() const { return mWhiskerWidth; } + double symbolGap() const { return mSymbolGap; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &error); + void setData(const QVector &errorMinus, const QVector &errorPlus); + void setDataPlottable(QCPAbstractPlottable* plottable); + void setErrorType(ErrorType type); + void setWhiskerWidth(double pixels); + void setSymbolGap(double pixels); + + // non-property methods: + void addData(const QVector &error); + void addData(const QVector &errorMinus, const QVector &errorPlus); + void addData(double error); + void addData(double errorMinus, double errorPlus); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const Q_DECL_OVERRIDE; + virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; + virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; + virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; + virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer mDataContainer; + QPointer mDataPlottable; + ErrorType mErrorType; + double mWhiskerWidth; + double mSymbolGap; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; + void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; + // helpers: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + bool errorBarVisible(int index) const; + bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-errorbar.h' */ + + +/* including file 'src/items/item-straightline.h' */ +/* modified 2021-03-29T02:30:44, size 3137 */ + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-straightline.h' */ + + +/* including file 'src/items/item-line.h' */ +/* modified 2021-03-29T02:30:44, size 3429 */ + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-line.h' */ + + +/* including file 'src/items/item-curve.h' */ +/* modified 2021-03-29T02:30:44, size 3401 */ + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; + +/* end of 'src/items/item-curve.h' */ + + +/* including file 'src/items/item-rect.h' */ +/* modified 2021-03-29T02:30:44, size 3710 */ + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-rect.h' */ + + +/* including file 'src/items/item-text.h' */ +/* modified 2021-03-29T02:30:44, size 5576 */ + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + explicit QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText() Q_DECL_OVERRIDE; + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-text.h' */ + + +/* including file 'src/items/item-ellipse.h' */ +/* modified 2021-03-29T02:30:44, size 3890 */ + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-ellipse.h' */ + + +/* including file 'src/items/item-pixmap.h' */ +/* modified 2021-03-29T02:30:44, size 4407 */ + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap() Q_DECL_OVERRIDE; + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=nullptr, bool *flippedVert=nullptr) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-pixmap.h' */ + + +/* including file 'src/items/item-tracer.h' */ +/* modified 2021-03-29T02:30:44, size 4811 */ + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + explicit QCPItemTracer(QCustomPlot *parentPlot); + virtual ~QCPItemTracer() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setInterpolating(bool enabled); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + double mGraphKey; + bool mInterpolating; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; +Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) + +/* end of 'src/items/item-tracer.h' */ + + +/* including file 'src/items/item-bracket.h' */ +/* modified 2021-03-29T02:30:44, size 3991 */ + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + /*! + Defines the various visual shapes of the bracket item. The appearance can be further modified + by \ref setLength and \ref setPen. + + \see setStyle + */ + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + Q_ENUMS(BracketStyle) + + explicit QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket() Q_DECL_OVERRIDE; + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; +Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) + +/* end of 'src/items/item-bracket.h' */ + + +/* including file 'src/polar/radialaxis.h' */ +/* modified 2021-03-29T02:30:44, size 12227 */ + + +class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + + /// \endcond +public: + /*! + Defines the reference of the angle at which a radial axis is tilted (\ref setAngle). + */ + enum AngleReference { arAbsolute ///< The axis tilt is given in absolute degrees. The zero is to the right and positive angles are measured counter-clockwise. + ,arAngularAxis ///< The axis tilt is measured in the angular coordinate system given by the parent angular axis. + }; + Q_ENUMS(AngleReference) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + enum LabelMode { lmUpright ///< + ,lmRotated ///< + }; + Q_ENUMS(LabelMode) + + explicit QCPPolarAxisRadial(QCPPolarAxisAngular *parent); + virtual ~QCPPolarAxisRadial(); + + // getters: + bool rangeDrag() const { return mRangeDrag; } + bool rangeZoom() const { return mRangeZoom; } + double rangeZoomFactor() const { return mRangeZoomFactor; } + + QCPPolarAxisAngular *angularAxis() const { return mAngularAxis; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + double angle() const { return mAngle; } + AngleReference angleReference() const { return mAngleReference; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const { return mLabelPainter.padding(); } + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const { return mLabelPainter.rotation(); } + LabelMode tickLabelMode() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector subTickVector() const { return mSubTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + + // setters: + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + void setRangeZoomFactor(double factor); + + Q_SLOT void setScaleType(QCPPolarAxisRadial::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setAngle(double degrees); + void setAngleReference(AngleReference reference); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelMode(LabelMode mode); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPPolarAxisRadial::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPPolarAxisRadial::SelectableParts &selectedParts); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-property methods: + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void rescale(bool onlyVisiblePlottables=false); + void pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const; + QPointF coordToPixel(double angleCoord, double radiusCoord) const; + double coordToRadius(double coord) const; + double radiusToCoord(double radius) const; + SelectablePart getPartAt(const QPointF &pos) const; + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPPolarAxisRadial::ScaleType scaleType); + void selectionChanged(const QCPPolarAxisRadial::SelectableParts &parts); + void selectableChanged(const QCPPolarAxisRadial::SelectableParts &parts); + +protected: + // property members: + bool mRangeDrag; + bool mRangeZoom; + double mRangeZoomFactor; + + // axis base: + QCPPolarAxisAngular *mAngularAxis; + double mAngle; + AngleReference mAngleReference; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + // axis label: + int mLabelPadding; + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; in label painter + bool mTickLabels; + //double mTickLabelRotation; in label painter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + bool mNumberMultiplyCross; + // ticks and subticks: + bool mTicks; + bool mSubTicks; + int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QPointF mCenter; + double mRadius; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mDragging; + QCPRange mDragStartRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QCPLabelPainterPrivate mLabelPainter; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + // mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateGeometry(const QPointF ¢er, double radius); + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPPolarAxisRadial) + + friend class QCustomPlot; + friend class QCPPolarAxisAngular; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarAxisRadial::SelectableParts) +Q_DECLARE_METATYPE(QCPPolarAxisRadial::AngleReference) +Q_DECLARE_METATYPE(QCPPolarAxisRadial::ScaleType) +Q_DECLARE_METATYPE(QCPPolarAxisRadial::SelectablePart) + + + +/* end of 'src/polar/radialaxis.h' */ + + +/* including file 'src/polar/layoutelement-angularaxis.h' */ +/* modified 2021-03-29T02:30:44, size 13461 */ + +class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + + /// \endcond +public: + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + /*! + TODO + */ + enum LabelMode { lmUpright ///< + ,lmRotated ///< + }; + Q_ENUMS(LabelMode) + + explicit QCPPolarAxisAngular(QCustomPlot *parentPlot); + virtual ~QCPPolarAxisAngular(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + bool rangeDrag() const { return mRangeDrag; } + bool rangeZoom() const { return mRangeZoom; } + double rangeZoomFactor() const { return mRangeZoomFactor; } + + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + double angle() const { return mAngle; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const { return mLabelPainter.padding(); } + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const { return mLabelPainter.rotation(); } + LabelMode tickLabelMode() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const { return mTickLengthIn; } + int tickLengthOut() const { return mTickLengthOut; } + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const { return mSubTickLengthIn; } + int subTickLengthOut() const { return mSubTickLengthOut; } + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const { return mLabelPadding; } + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPPolarGrid *grid() const { return mGrid; } + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + void setRangeZoomFactor(double factor); + + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setAngle(double degrees); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelMode(LabelMode mode); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setLabelPosition(Qt::AlignmentFlag position); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPPolarAxisAngular::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPPolarAxisAngular::SelectableParts &selectedParts); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // non-property methods: + bool removeGraph(QCPPolarGraph *graph); + int radialAxisCount() const; + QCPPolarAxisRadial *radialAxis(int index=0) const; + QList radialAxes() const; + QCPPolarAxisRadial *addRadialAxis(QCPPolarAxisRadial *axis=0); + bool removeRadialAxis(QCPPolarAxisRadial *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + QRegion exactClipRegion() const; + + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void rescale(bool onlyVisiblePlottables=false); + double coordToAngleRad(double coord) const { return mAngleRad+(coord-mRange.lower)/mRange.size()*(mRangeReversed ? -2.0*M_PI : 2.0*M_PI); } // mention in doc that return doesn't wrap + double angleRadToCoord(double angleRad) const { return mRange.lower+(angleRad-mAngleRad)/(mRangeReversed ? -2.0*M_PI : 2.0*M_PI)*mRange.size(); } + void pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const; + QPointF coordToPixel(double angleCoord, double radiusCoord) const; + SelectablePart getPartAt(const QPointF &pos) const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPointF center() const { return mCenter; } + double radius() const { return mRadius; } + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void selectionChanged(const QCPPolarAxisAngular::SelectableParts &parts); + void selectableChanged(const QCPPolarAxisAngular::SelectableParts &parts); + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + bool mRangeDrag; + bool mRangeZoom; + double mRangeZoomFactor; + + // axis base: + double mAngle, mAngleRad; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + // axis label: + int mLabelPadding; + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; in label painter + bool mTickLabels; + //double mTickLabelRotation; in label painter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + bool mNumberMultiplyCross; + // ticks and subticks: + bool mTicks; + bool mSubTicks; + int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + + // non-property members: + QPointF mCenter; + double mRadius; + QList mRadialAxes; + QCPPolarGrid *mGrid; + QList mGraphs; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mTickVectorCosSin; + QVector mSubTickVector; + QVector mSubTickVectorCosSin; + bool mDragging; + QCPRange mDragAngularStart; + QList mDragRadialStart; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QCPLabelPainterPrivate mLabelPainter; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-virtual methods: + bool registerPolarGraph(QCPPolarGraph *graph); + void drawBackground(QCPPainter *painter, const QPointF ¢er, double radius); + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPPolarAxisAngular) + + friend class QCustomPlot; + friend class QCPPolarGrid; + friend class QCPPolarGraph; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarAxisAngular::SelectableParts) +Q_DECLARE_METATYPE(QCPPolarAxisAngular::SelectablePart) + +/* end of 'src/polar/layoutelement-angularaxis.h' */ + + +/* including file 'src/polar/polargrid.h' */ +/* modified 2021-03-29T02:30:44, size 4506 */ + +class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + + /// \endcond +public: + /*! + TODO + */ + enum GridType { gtAngular = 0x01 ///< + ,gtRadial = 0x02 ///< + ,gtAll = 0xFF ///< + ,gtNone = 0x00 ///< + }; + Q_ENUMS(GridType) + Q_FLAGS(GridTypes) + Q_DECLARE_FLAGS(GridTypes, GridType) + + explicit QCPPolarGrid(QCPPolarAxisAngular *parentAxis); + + // getters: + QCPPolarAxisRadial *radialAxis() const { return mRadialAxis.data(); } + GridTypes type() const { return mType; } + GridTypes subGridType() const { return mSubGridType; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen angularPen() const { return mAngularPen; } + QPen angularSubGridPen() const { return mAngularSubGridPen; } + QPen radialPen() const { return mRadialPen; } + QPen radialSubGridPen() const { return mRadialSubGridPen; } + QPen radialZeroLinePen() const { return mRadialZeroLinePen; } + + // setters: + void setRadialAxis(QCPPolarAxisRadial *axis); + void setType(GridTypes type); + void setSubGridType(GridTypes type); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setAngularPen(const QPen &pen); + void setAngularSubGridPen(const QPen &pen); + void setRadialPen(const QPen &pen); + void setRadialSubGridPen(const QPen &pen); + void setRadialZeroLinePen(const QPen &pen); + +protected: + // property members: + GridTypes mType; + GridTypes mSubGridType; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mAngularPen, mAngularSubGridPen; + QPen mRadialPen, mRadialSubGridPen, mRadialZeroLinePen; + + // non-property members: + QCPPolarAxisAngular *mParentAxis; + QPointer mRadialAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawRadialGrid(QCPPainter *painter, const QPointF ¢er, const QVector &coords, const QPen &pen, const QPen &zeroPen=Qt::NoPen); + void drawAngularGrid(QCPPainter *painter, const QPointF ¢er, double radius, const QVector &ticksCosSin, const QPen &pen); + +private: + Q_DISABLE_COPY(QCPPolarGrid) + +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarGrid::GridTypes) +Q_DECLARE_METATYPE(QCPPolarGrid::GridType) + + +/* end of 'src/polar/polargrid.h' */ + + +/* including file 'src/polar/polargraph.h' */ +/* modified 2021-03-29T02:30:44, size 9606 */ + + +class QCP_LIB_DECL QCPPolarLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPolarLegendItem(QCPLegend *parent, QCPPolarGraph *graph); + + // getters: + QCPPolarGraph *polarGraph() { return mPolarGraph; } + +protected: + // property members: + QCPPolarGraph *mPolarGraph; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + }; + Q_ENUMS(LineStyle) + + QCPPolarGraph(QCPPolarAxisAngular *keyAxis, QCPPolarAxisRadial *valueAxis); + virtual ~QCPPolarGraph(); + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + bool periodic() const { return mPeriodic; } + QCPPolarAxisAngular *keyAxis() const { return mKeyAxis.data(); } + QCPPolarAxisRadial *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + //QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPeriodic(bool enabled); + void setKeyAxis(QCPPolarAxisAngular *axis); + void setValueAxis(QCPPolarAxisRadial *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + //void setSelectionDecorator(QCPSelectionDecorator *decorator); + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables + virtual QCPPlottableInterface1D *interface1D() { return 0; } // TODO: return this later, when QCPAbstractPolarPlottable is created + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QSharedPointer mDataContainer; + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + QString mName; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + bool mPeriodic; + QPointer mKeyAxis; + QPointer mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + //QCPSelectionDecorator *mSelectionDecorator; + + // introduced virtual methods (later reimplemented TODO from QCPAbstractPolarPlottable): + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter); + virtual QCP::Interaction selectionCategory() const; + void applyDefaultAntialiasingHint(QCPPainter *painter) const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // virtual drawing helpers: + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + // drawing helpers: + virtual int dataCount() const; + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData) const; + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + QVector dataToLines(const QVector &data) const; + +private: + Q_DISABLE_COPY(QCPPolarGraph) + + friend class QCPPolarLegendItem; +}; + +/* end of 'src/polar/polargraph.h' */ + + +#endif // QCUSTOMPLOT_H + diff --git a/ChaosDataPlayer/qrc.qrc b/ChaosDataPlayer/qrc.qrc new file mode 100644 index 0000000..0360cd9 --- /dev/null +++ b/ChaosDataPlayer/qrc.qrc @@ -0,0 +1,183 @@ + + + images/imgTreeIcon/remove2.png + images/imgTreeIcon/remove6.png + images/imgTreeIcon/config.png + images/imgTreeIcon/data.png + images/imgTreeIcon/channel.png + images/imgTreeIcon/artic66.png + images/imgDatamodel/M1.png + images/imgDatamodel/M2.png + images/imgDatamodel/M3.png + images/imgDatamodel/M4.png + images/imgDatamodel/M5.png + images/imgDatamodel/M6.png + images/imgDatamodel/M7.png + images/imgDatamodel/M8.png + images/imgDatamodel/M9.png + images/imgDatamodel/M10.png + images/imgDatamodel/M11.png + images/imgDatamodel/M12.png + images/bg_main.png + images/bg_top.png + images/close_h.png + images/close_n.png + images/close_s.png + images/line.png + images/max_h.png + images/max_n.png + images/max_s.png + images/min_h.png + images/min_n.png + images/min_s.png + images/restore_h.png + images/restore_n.png + images/restore_s.png + images/imgMenuBar/B1.png + images/imgMenuBar/B2.png + images/imgMenuBar/B3.png + images/imgMenuBar/B4.png + images/imgMenuBar/B5.png + images/imgMenuBar/B6.png + images/imgMenuBar/B7.png + images/imgPlay/B8.png + images/imgPlay/B9.png + images/imgPlay/B10.png + images/imgPlay/B11.png + images/imgPlay/B12.png + images/imgPlay/B13.png + images/imgPlay/B14.png + images/imgPlay/B15.png + images/imgPlay/B16.png + images/imgModelAction/344.png + images/imgSystem/systemIcon.png + images/imgDatamodel/M1-h.png + images/imgDatamodel/M1-p.png + images/imgDatamodel/M2-h.png + images/imgDatamodel/M2-p.png + images/imgDatamodel/M3-h.png + images/imgDatamodel/M3-p.png + images/imgDatamodel/M4-h.png + images/imgDatamodel/M4-p.png + images/imgDatamodel/M5-h.png + images/imgDatamodel/M5-p.png + images/imgDatamodel/M6-h.png + images/imgDatamodel/M6-p.png + images/imgDatamodel/M7-h.png + images/imgDatamodel/M7-p.png + images/imgDatamodel/M8-h.png + images/imgDatamodel/M8-p.png + images/imgDatamodel/M9-h.png + images/imgDatamodel/M9-p.png + images/imgDatamodel/M10-h.png + images/imgDatamodel/M10-p.png + images/imgDatamodel/M11-h.png + images/imgDatamodel/M11-p.png + images/imgDatamodel/M12-h.png + images/imgDatamodel/M12-p.png + images/hideChannel.png + images/showChannel.png + images/imgMenuBar/B1-h.png + images/imgMenuBar/B2-h.png + images/imgMenuBar/B3-h.png + images/imgMenuBar/B4-h.png + images/imgMenuBar/B5-h.png + images/imgMenuBar/B6-h.png + images/imgMenuBar/B7-h.png + images/imgPlay/B8-h.png + images/imgPlay/B9-h.png + images/imgPlay/B10-h.png + images/imgPlay/B11-h.png + images/imgPlay/B12-h.png + images/imgPlay/B13-h.png + images/imgPlay/B14-h.png + images/imgDatamodel/tabclose.png + images/imgDatamodel/tabclose-h.png + images/imgDatamodel/tabclose-p.png + images/imgModelAction/axisX.png + images/imgModelAction/axisX-h.png + images/imgModelAction/axisX-p.png + images/imgModelAction/axisY.png + images/imgModelAction/axisY-h.png + images/imgModelAction/axisY-p.png + images/imgModelAction/hand.png + images/imgModelAction/hand-h.png + images/imgModelAction/hand-p.png + images/imgModelAction/measure.png + images/imgModelAction/measure-h.png + images/imgModelAction/measure-p.png + images/imgModelAction/realTime.png + images/imgModelAction/realTime-p.png + images/imgModelAction/AC.png + images/imgModelAction/AC-h.png + images/imgModelAction/arf.png + images/imgModelAction/arf-h.png + images/imgModelAction/gb1.png + images/imgModelAction/HZ.png + images/imgModelAction/HZ-h.png + images/imgModelAction/lvbo.png + images/imgModelAction/lvbo-h.png + images/imgModelAction/lvbo-p.jpg + images/imgModelAction/TDBC.png + images/imgModelAction/TDBC-h.png + images/imgModelAction/doubleIntegration.png + images/imgModelAction/Integration.png + images/imgModelAction/Zoom-h.png + images/imgModelAction/Zoom-p.png + images/imgModelAction/Zoom_xy.png + images/imgModelAction/Zoom-xy-h.png + images/imgModelAction/Zoom-xy-p.png + images/imgModelAction/hand1.png + images/imgModelAction/setScales.png + images/imgModelAction/setScales-h.png + images/imgModelAction/setScales-p.png + images/imgModelAction/Annotation.png + images/imgModelAction/Annotation-h.png + images/imgModelAction/Annotation-p.png + images/imgModelAction/realTime-h.png + images/imgModelAction/Sound.png + images/imgModelAction/Sound-h.png + images/imgModelAction/Sound-p.png + images/imgModelAction/doublearf.png + images/imgModelAction/gb-h.png + images/imgModelAction/gb-p.png + images/imgModelAction/TDBC-p.png + images/imgModelAction/lvbo-p.png + images/logo.png + images/imgModelAction/Zoom_Box.png + images/imgModelAction/Zoom_X.png + images/imgModelAction/Zoom_Y.png + images/imgModelAction/Zoom-XY.png + images/imgModelAction/biandai.png + images/imgModelAction/fengzhi.png + images/imgModelAction/xiebo.png + images/imgModelAction/Cursor.png + images/imgModelAction/Open.png + images/imgModelAction/Open_h.png + images/imgModelAction/Open_p.png + images/imgModelAction/Close.png + images/imgModelAction/Close_h.png + images/imgModelAction/Close_p.png + images/imgModelAction/Ord.png + images/imgModelAction/rpm.png + images/imgModelAction/hz-2.png + images/imgModelAction/arf-p.png + images/imgModelAction/Search.png + images/imgModelAction/Zoom.png + images/imgModelAction/Search-h.png + images/imgModelAction/Search-p.png + images/imgSystem/ICON.ico + images/imgModelAction/AC-p.png + images/imgModelAction/DC.png + images/imgModelAction/measure-d.png + images/imgModelAction/Annotation1.png + images/imgModelAction/Sound-d.png + images/imgModelAction/realTime-d.png + images/logo1.png + images/loading.gif + + + mainui.css + + + diff --git a/ChaosDataPlayer/secure.cpp b/ChaosDataPlayer/secure.cpp new file mode 100644 index 0000000..b9317fb --- /dev/null +++ b/ChaosDataPlayer/secure.cpp @@ -0,0 +1,94 @@ +#include "secure.h" +#include "global.h" + +Secure::Secure() +{ + +} + +char * Secure::Base64Encode(const unsigned char * bindata, char * base64, int binlength) +{ + int i, j; + unsigned char current; + const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + for (i = 0, j = 0; i < binlength; i += 3) + { + current = (bindata[i] >> 2); + current &= (unsigned char)0x3F; + base64[j++] = base64char[(int)current]; + + current = ((unsigned char)(bindata[i] << 4)) & ((unsigned char)0x30); + if (i + 1 >= binlength) + { + base64[j++] = base64char[(int)current]; + base64[j++] = '='; + base64[j++] = '='; + break; + } + current |= ((unsigned char)(bindata[i + 1] >> 4)) & ((unsigned char)0x0F); + base64[j++] = base64char[(int)current]; + + current = ((unsigned char)(bindata[i + 1] << 2)) & ((unsigned char)0x3C); + if (i + 2 >= binlength) + { + base64[j++] = base64char[(int)current]; + base64[j++] = '='; + break; + } + current |= ((unsigned char)(bindata[i + 2] >> 6)) & ((unsigned char)0x03); + base64[j++] = base64char[(int)current]; + + current = ((unsigned char)bindata[i + 2]) & ((unsigned char)0x3F); + base64[j++] = base64char[(int)current]; + } + base64[j] = '\0'; + return base64; +} + +int Secure::Base64Decode( const char * base64, unsigned char * bindata) +{ + int i, j; + unsigned char k; + unsigned char temp[4]; + const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 ) + { + memset( temp, 0xFF, sizeof(temp) ); + for ( k = 0 ; k < 64 ; k ++ ) + { + if ( base64char[k] == base64[i] ) + temp[0]= k; + } + for ( k = 0 ; k < 64 ; k ++ ) + { + if ( base64char[k] == base64[i+1] ) + temp[1]= k; + } + for ( k = 0 ; k < 64 ; k ++ ) + { + if ( base64char[k] == base64[i+2] ) + temp[2]= k; + } + for ( k = 0 ; k < 64 ; k ++ ) + { + if ( base64char[k] == base64[i+3] ) + temp[3]= k; + } + + bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) | + ((unsigned char)((unsigned char)(temp[1]>>4)&0x03)); + if ( base64[i+2] == '=' ) + break; + + bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) | + ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F)); + if ( base64[i+3] == '=' ) + break; + + bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) | + ((unsigned char)(temp[3]&0x3F)); + } + return j; +} diff --git a/ChaosDataPlayer/secure.h b/ChaosDataPlayer/secure.h new file mode 100644 index 0000000..a9b9ba3 --- /dev/null +++ b/ChaosDataPlayer/secure.h @@ -0,0 +1,14 @@ +#ifndef SECURE_H +#define SECURE_H +#include +#include "SH_MySingleton.hpp" + +class Secure: public MySingleton +{ +public: + Secure(); + char *Base64Encode(const unsigned char * bindata, char * base65, int binlength); + int Base64Decode( const char * base64, unsigned char * bindata); +}; + +#endif // SECURE_H diff --git a/ChaosDataPlayer/sqlitedb.cpp b/ChaosDataPlayer/sqlitedb.cpp new file mode 100644 index 0000000..21c9f51 --- /dev/null +++ b/ChaosDataPlayer/sqlitedb.cpp @@ -0,0 +1,213 @@ +#include "sqlitedb.h" + + +SqliteDB::SqliteDB() +{ + + +} + +int SqliteDB::OpenDataBase() +{ + QDir pluginsDir(QLibraryInfo::location(QLibraryInfo::PluginsPath)); + QString path1 = pluginsDir.absolutePath(); + qDebug("Plugins path : %s", qPrintable(path1)); + + QString path = QDir::currentPath(); + QApplication::addLibraryPath(path); + QPluginLoader loader(QString("./plugins/sqldrivers/qsqlite.dll")); + + + database = QSqlDatabase::addDatabase("QSQLITE"); + database.setDatabaseName(QCoreApplication::applicationDirPath() + "\\DB\\analyse.db"); + if (!database.open()) + { + qDebug() << "Error: Failed to connect database." << database.lastError(); + return -1; + } + else + { + qDebug() << "Succeed to connect database." ; + return 0; + } +} +int SqliteDB::CreateDataBase() +{ + //创建表格 + QSqlQuery sql_query; + if(!sql_query.exec("create table if not exists t_Device(DeviceMac VARCHAR(32) primary key, DeviceName VARCHAR(100),\ + DeviceIP VARCHAR(32),DeviceType VARCHAR(32),Online VARCHAR(1))")) + { + qDebug() << "Error: Fail to create table."<< sql_query.lastError(); + return -1; + } + else + { + qDebug() << "Table created!"; + return 0; + } + +} +int SqliteDB::QueryData(QString& tablename, QString& column, QString& whereCon) +{ + QSqlQuery sql_query; + QString strSql = "select "; + if (whereCon != NULL) { + strSql = strSql + column + " from " + tablename + " where " + whereCon + ";"; + } + else { + strSql = strSql + column + " from " + tablename + ";"; + } + int count = -1; + sql_query.exec(strSql); + if(!sql_query.exec()) + { + qDebug()< vecResult; + QString strSql = "select "; + if (whereCon != "") { + strSql = strSql + column + ", DeviceMac , DeviceName" + " from " + tablename + " where " + whereCon + ";"; + } + else { + strSql = strSql + column + ", DeviceMac , DeviceName" + " from " + tablename + ";"; + } + qDebug() << "strSql" << strSql << endl; + sql_query.exec(strSql); + while(sql_query.next()){ + vec_t arrResult; + QString strIP = sql_query.value(0).toString(); + arrResult.push_back(strIP); + arrResult.push_back(sql_query.value(1).toString()); + arrResult.push_back(sql_query.value(2).toString()); + vecResult.push_back(arrResult); + } + return vecResult; + } +int SqliteDB::InsertData(QString& tablename,QString& sql) +{ + QSqlQuery sql_query; + QString strSql = "INSERT INTO "; + strSql = strSql + tablename + sql; + if(!sql_query.exec(strSql)) + { + qDebug() << sql_query.lastError(); + } + else + { + qDebug() << ""; + } + +} +int SqliteDB::UpdataData(QString& tablename, QString& columnName, QString& columnValue, QString whereColName, QString whereColValue) +{ + QSqlQuery sql_query; + int iRet = -1; + QString strSql = "update "; + if (whereColName != NULL) { + strSql = strSql + tablename + " set " + columnName + "='" + columnValue + "'" + " where " + whereColName + "='" + whereColValue + "';"; + } + else { + strSql = strSql + tablename + " set " + columnName + "='" + columnValue + "';"; + } + + if(!sql_query.exec(strSql)) + { + qDebug() << sql_query.lastError(); + } + else + { + iRet = 0; + qDebug() << ""; + } + return iRet; +} +int SqliteDB::UpdataDataCol(QString& tablename, QString& updateColumn, QString& whereCond) +{ + QSqlQuery sql_query; + int iRet = -1; + QString strSql = "update "; + if (whereCond != NULL) { + strSql = strSql + tablename + " set " + updateColumn + " where " + whereCond; + } + else { + strSql = strSql + tablename + " set " + updateColumn ; + } + qDebug() << "strSql" << strSql << endl; + if(!sql_query.exec(strSql)) + { + qDebug() << sql_query.lastError(); + } + else + { + iRet = 0; + qDebug() << ""; + } + return iRet; +} + +int SqliteDB::DeleteData(QString& tablename, QString& condColumnName, QString& condColumnValue) +{ + QSqlQuery sql_query; + int iRet = -1; + QString strSql = "delete from "; + if (condColumnName != NULL) { + strSql = strSql + tablename + " where " + condColumnName + "='" + condColumnValue + "';"; + } + else { + strSql = strSql + tablename + ";"; + } + if(!sql_query.exec(strSql)) + { + qDebug() << sql_query.lastError(); + } + else + { + iRet = 0; + qDebug() << ""; + } + return iRet; +} +int SqliteDB::InitDevice() +{ + QString tableName = "t_Device "; + QString column = "Online"; + QString columnValue = "0"; + UpdataData(tableName,column,columnValue); +} +int SqliteDB::OperateDeviceData(DEVICE_INFO& device_info) +{ + if(device_info.DeviceMac == "" || device_info.DeviceIP == "") + return 0; + QString whereCon = QString("DeviceMac = '%1'").arg(device_info.DeviceMac); + QString tableName = "t_Device "; + QString column = "count(*)"; + int iRet = QueryData(tableName,column,whereCon); + qDebug() << "QueryData " < +#include +#include +#include +#include +#include +#include +#include +#include "global.h" + +typedef QVector vec_t; +typedef QVector array_t; + +class SqliteDB +{ +public: + SqliteDB(); + QSqlDatabase database; + int OpenDataBase(); + int CreateDataBase(); + int InsertData(QString& tablename,QString& sql); + int UpdataData(QString& tablename, QString& columnName, QString& columnValue, QString whereColName = "", QString whereColValue = ""); + int UpdataDataCol(QString& tablename, QString& updateColumn, QString& whereCond); + int QueryData(QString& tablename, QString& column, QString& whereCon); + array_t GetDataMultiLine(QString& tablename, QString& column, QString whereCon = ""); + int DeleteData(QString& tablename, QString& condColumnName, QString& condColumnValue); + int OperateDeviceData(DEVICE_INFO& device_info); + int InitDevice(); +}; + +#endif // SQLITEDB_H diff --git a/ChaosDataPlayer/ui_widget.h b/ChaosDataPlayer/ui_widget.h new file mode 100644 index 0000000..25b6a0c --- /dev/null +++ b/ChaosDataPlayer/ui_widget.h @@ -0,0 +1,65 @@ +/******************************************************************************** +** Form generated from reading UI file 'widget.ui' +** +** Created by: Qt User Interface Compiler version 5.13.2 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_WIDGET_H +#define UI_WIDGET_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_Widget +{ +public: + QVBoxLayout *verticalLayout; + QTabWidget *tabWidget; + QPushButton *pushButton; + + void setupUi(QWidget *Widget) + { + if (Widget->objectName().isEmpty()) + Widget->setObjectName(QString::fromUtf8("Widget")); + Widget->resize(818, 600); + verticalLayout = new QVBoxLayout(Widget); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + tabWidget = new QTabWidget(Widget); + tabWidget->setObjectName(QString::fromUtf8("tabWidget")); + + verticalLayout->addWidget(tabWidget); + + pushButton = new QPushButton(Widget); + pushButton->setObjectName(QString::fromUtf8("pushButton")); + + verticalLayout->addWidget(pushButton); + + + retranslateUi(Widget); + + QMetaObject::connectSlotsByName(Widget); + } // setupUi + + void retranslateUi(QWidget *Widget) + { + Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr)); + pushButton->setText(QCoreApplication::translate("Widget", "PushButton", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class Widget: public Ui_Widget {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_WIDGET_H