97
189
QString MatrixModel::text(int row, int col)
99
191
int i = d_cols*row + col;
100
if (i < 0 || i>= d_data.size() || gsl_isnan (d_data[i]))
192
double val = d_data[i];
193
if (i < 0 || i>= d_rows*d_cols || gsl_isnan(val))
103
QLocale locale = d_matrix->locale();
104
return locale.toString(d_data[i], d_matrix->textFormat().toAscii(), d_matrix->precision());
197
QLocale locale = d_matrix->locale();
198
return locale.toString(val, d_matrix->textFormat().toAscii(), d_matrix->precision());
200
return d_locale.toString(val, d_txt_format, d_num_precision);
107
203
void MatrixModel::setText(int row, int col, const QString& text)
109
205
int i = d_cols*row + col;
110
if (i < 0 || i>= d_data.size())
206
if (i < 0 || i>= d_rows*d_cols)
113
209
if (text.isEmpty())
114
210
d_data[i] = GSL_NAN;
116
d_data[i] = text.toDouble();
213
d_data[i] = d_matrix->locale().toDouble(text);
215
d_data[i] = d_locale.toDouble(text);
119
219
double MatrixModel::data(int row, int col) const
121
221
int i = d_cols*row + col;
122
if (i < 0 || i>= d_data.size())
222
if (i < 0 || i>= d_rows*d_cols)
125
225
return d_data[i];
228
double MatrixModel::x(int col) const
230
if (col < 0 || col >= d_cols)
233
double start = d_matrix->xStart();
234
double end = d_matrix->xEnd();
236
return start + col*d_matrix->dx();
238
return start - col*d_matrix->dx();
243
double MatrixModel::y(int row) const
245
if (row < 0 || row >= d_rows)
248
double start = d_matrix->yStart();
249
double end = d_matrix->yEnd();
251
return start + row*d_matrix->dy();
253
return start - row*d_matrix->dy();
128
258
QVariant MatrixModel::headerData ( int section, Qt::Orientation orientation, int role) const
130
if (d_matrix->headerViewType() == Matrix::ColumnRow)
260
if (!d_matrix || d_matrix->headerViewType() == Matrix::ColumnRow)
131
261
return QAbstractItemModel::headerData(section, orientation, role);
133
QLocale locale = d_matrix->locale();
263
QLocale locale = d_locale;
264
int prec = d_num_precision;
265
char fmt = d_txt_format;
267
locale = d_matrix->locale();
268
fmt = d_matrix->textFormat().toAscii();
269
prec = d_matrix->precision();
134
272
if (role == Qt::DisplayRole || role == Qt::EditRole){
135
273
if (orientation == Qt::Horizontal){
136
274
double start = d_matrix->xStart();
137
275
double end = d_matrix->xEnd();
138
276
double dx = d_matrix->dx();
140
return QVariant(locale.toString(start + section*dx, d_matrix->textFormat().toAscii(), d_matrix->precision()));
278
return QVariant(locale.toString(start + section*dx, fmt, prec));
142
return QVariant(locale.toString(start - section*dx, d_matrix->textFormat().toAscii(), d_matrix->precision()));
280
return QVariant(locale.toString(start - section*dx, fmt, prec));
143
281
} else if (orientation == Qt::Vertical){
144
282
double start = d_matrix->yStart();
145
283
double end = d_matrix->yEnd();
146
284
double dy = d_matrix->dy();
148
return QVariant(locale.toString(start + section*dy, d_matrix->textFormat().toAscii(), d_matrix->precision()));
286
return QVariant(locale.toString(start + section*dy, fmt, prec));
150
return QVariant(locale.toString(start - section*dy, d_matrix->textFormat().toAscii(), d_matrix->precision()));
288
return QVariant(locale.toString(start - section*dy, fmt, prec));
153
return QAbstractItemModel::headerData(section, orientation, role);
291
return QAbstractItemModel::headerData(section, orientation, role);
156
294
QVariant MatrixModel::data(const QModelIndex &index, int role) const
309
491
for ( int i = 0; i < d_rows; i++ ){
310
492
QRgb *line = (QRgb *)image.scanLine(i);
311
493
for ( int j = 0; j < d_cols; j++){
312
if(fabs(d_data[i*d_cols + j]) < HUGE_VAL)
313
*line++ = color_map.rgb(intensityRange, d_data[i*d_cols + j]);
494
double val = d_data[i*d_cols + j];
496
*line++ = color_map.rgb(intensityRange, 0.0);
497
else if(fabs(val) < HUGE_VAL)
498
*line++ = color_map.rgb(intensityRange, val);
501
QApplication::restoreOverrideCursor();
319
void MatrixModel::setDataVector(const QVector<double>& data)
505
bool MatrixModel::importASCII(const QString &fname, const QString &sep, int ignoredLines,
506
bool stripSpaces, bool simplifySpaces, const QString& commentString, int importAs,
507
const QLocale& locale, int endLineChar, int maxRows)
510
QString name = MdiSubWindow::parseAsciiFile(fname, commentString, endLineChar, ignoredLines, maxRows, rows);
514
if (!f.open(QIODevice::ReadOnly))
517
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
520
QLocale l = d_locale;
522
l = d_matrix->locale();
523
bool updateDecimalSeparators = (l != locale) ? true : false;
525
QString s = t.readLine();
527
s = s.simplifyWhiteSpace();
528
else if (stripSpaces)
529
s = s.stripWhiteSpace();
531
QStringList line = s.split(sep);
532
int cols = line.size();
534
int startRow = 1, startCol = 0;
536
case Matrix::Overwrite:
538
setColumnCount(cols);
542
case Matrix::NewColumns:
544
setColumnCount(d_cols + cols);
548
case Matrix::NewRows:
551
setColumnCount(cols);
552
setRowCount(d_rows + rows);
556
for (int j = startCol; j<d_cols; j++){
557
int aux = j - startCol;
559
if (updateDecimalSeparators)
560
setCell(0, j, locale.toDouble(line[aux]));
562
setText(0, j, line[aux]);
566
qApp->processEvents(QEventLoop::ExcludeUserInput);
567
for (int i = startRow; i<d_rows; i++){
570
s = s.simplifyWhiteSpace();
571
else if (stripSpaces)
572
s = s.stripWhiteSpace();
574
int lc = line.size();
576
setColumnCount(d_cols + lc - cols);
578
for (int j = startCol; j<d_cols; j++){
579
int aux = j - startCol;
581
if (updateDecimalSeparators)
582
setCell(i, j, locale.toDouble(line[aux]));
584
setText(i, j, line[aux]);
588
f.remove(); //remove temp file
589
d_matrix->resetView();
590
QApplication::restoreOverrideCursor();
594
void MatrixModel::setNumericFormat(char f, int prec)
596
if (d_txt_format == f && d_num_precision == prec)
600
d_num_precision = prec;
603
void MatrixModel::transpose()
605
int size = d_rows*d_cols;
606
double *data = d_matrix->initWorkspace(size);
610
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
611
for(int i = 0; i < size; i++)
614
int old_cols = d_cols;
618
for(int i = 0; i < d_rows; i++){
619
for(int j = 0; j < d_cols; j++)
620
d_data[aux++] = data[j*old_cols + i];
622
d_matrix->freeWorkspace();
623
QApplication::restoreOverrideCursor();
626
void MatrixModel::flipVertically()
628
int size = d_rows*d_cols;
629
double *data = d_matrix->initWorkspace(size);
633
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
634
for(int i = 0; i < size; i++)
638
for(int i = 0; i < d_rows; i++){
639
int row = (d_rows - i - 1)*d_cols;
640
for(int j = 0; j < d_cols; j++)
641
d_data[aux++] = data[row++];
643
d_matrix->freeWorkspace();
644
QApplication::restoreOverrideCursor();
647
void MatrixModel::flipHorizontally()
649
int size = d_rows*d_cols;
650
double *data = d_matrix->initWorkspace(size);
654
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
655
for(int i = 0; i < size; i++)
659
for(int i = 0; i < d_rows; i++){
661
for(int j = d_cols - 1; j >= 0; j--)
662
d_data[aux++] = data[row + j];
664
d_matrix->freeWorkspace();
665
QApplication::restoreOverrideCursor();
668
void MatrixModel::rotate90(bool clockwise)
670
int size = d_rows*d_cols;
671
double *data = d_matrix->initWorkspace(size);
675
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
676
for(int i = 0; i < size; i++)
679
int old_rows = d_rows;
680
int old_cols = d_cols;
685
int aux = old_rows - 1;
686
for(int i = 0; i < d_rows; i++){
687
for(int j = 0; j < d_cols; j++)
688
d_data[cell++] = data[(aux - j)*old_cols + i];
692
int aux = old_cols - 1;
693
for(int i = 0; i < d_rows; i++){
695
for(int j = 0; j < d_cols; j++)
696
d_data[cell++] = data[j*old_cols + k];
699
d_matrix->freeWorkspace();
700
QApplication::restoreOverrideCursor();
703
bool MatrixModel::initWorkspace()
705
gsl_set_error_handler_off();
707
if (!d_direct_matrix)
708
d_direct_matrix = gsl_matrix_alloc(d_rows, d_cols);
710
d_inv_matrix = gsl_matrix_alloc(d_rows, d_cols);
712
d_inv_perm = gsl_permutation_alloc(d_cols);
713
if (!d_direct_matrix || !d_inv_matrix || !d_inv_perm){
714
QApplication::restoreOverrideCursor();
715
QMessageBox::critical(d_matrix, tr("QtiPlot") + " - " + tr("Memory Allocation Error"),
716
tr("Not enough memory, operation aborted!"));
722
void MatrixModel::invert()
725
if(!d_direct_matrix || !d_inv_matrix || !d_inv_perm)
728
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
731
for(i=0; i<d_rows; i++){
732
for(int j=0; j<d_cols; j++)
733
gsl_matrix_set(d_direct_matrix, i, j, d_data[aux++]);
736
gsl_linalg_LU_decomp(d_direct_matrix, d_inv_perm, &i);
737
gsl_linalg_LU_invert(d_direct_matrix, d_inv_perm, d_inv_matrix);
739
gsl_matrix_free(d_direct_matrix);
740
d_direct_matrix = NULL;
741
gsl_permutation_free(d_inv_perm);
745
for(int i=0; i<d_rows; i++){
746
for(int j=0; j<d_cols; j++)
747
d_data[aux++] = gsl_matrix_get(d_inv_matrix, i, j);
749
gsl_matrix_free(d_inv_matrix);
751
QApplication::restoreOverrideCursor();
754
void MatrixModel::clear(int startRow, int endRow, int startCol, int endCol)
761
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
762
for (int i = startRow; i <= endRow; i++){
763
int aux = i*d_cols + startCol;
764
for (int j = startCol; j <= endCol; j++){
765
d_data[aux++] = GSL_NAN;
768
QApplication::restoreOverrideCursor();
771
double * MatrixModel::dataCopy(int startRow, int endRow, int startCol, int endCol)
778
double *buffer = (double *)malloc((endRow - startRow + 1)*(endCol - startCol + 1) * sizeof (double));
782
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
785
for (int i = startRow; i <= endRow; i++){
786
int row = i*d_cols + startCol;
787
for (int j = startCol; j <= endCol; j++){
788
buffer[aux++] = d_data[row++];
792
QApplication::restoreOverrideCursor();
796
bool MatrixModel::muParserCalculate(int startRow, int endRow, int startCol, int endCol)
798
ScriptingEnv *scriptEnv = d_matrix->scriptingEnv();
799
muParserScript *mup = new muParserScript(scriptEnv, d_matrix->formula(), d_matrix, QString("<%1>").arg(d_matrix->objectName()));
800
connect(mup, SIGNAL(error(const QString&,const QString&,int)), scriptEnv, SIGNAL(error(const QString&,const QString&,int)));
801
connect(mup, SIGNAL(print(const QString&)), scriptEnv, SIGNAL(print(const QString&)));
807
if (endCol >= d_cols)
808
setColumnCount(endCol + 1);
809
if (endRow >= d_rows)
810
setRowCount(endRow + 1);
812
double dx = d_matrix->dx();
813
double dy = d_matrix->dy();
814
double *ri = mup->defineVariable("i");
815
double *rr = mup->defineVariable("row");
816
double *cj = mup->defineVariable("j");
817
double *cc = mup->defineVariable("col");
818
double *x = mup->defineVariable("x");
819
double *y = mup->defineVariable("y");
821
if (!mup->compile()){
822
QApplication::restoreOverrideCursor();
826
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
828
double x_start = d_matrix->xStart();
829
double y_start = d_matrix->yStart();
830
if (mup->codeLines() == 1){
831
for(int row = startRow; row <= endRow; row++){
832
double r = row + 1.0;
834
*y = y_start + row*dy;
835
int aux = row*d_cols + startCol;
836
for(int col = startCol; col <= endCol; col++){
837
double c = col + 1.0;
839
*x = x_start + col*dx;
840
d_data[aux++] = mup->evalSingleLine();
845
for(int row = startRow; row <= endRow; row++){
846
double r = row + 1.0;
848
*y = y_start + row*dy;
849
int aux = row*d_cols + startCol;
850
for(int col = startCol; col <= endCol; col++){
851
double c = col + 1.0;
853
*x = x_start + col*dx;
855
if (res.canConvert(QVariant::Double))
856
d_data[aux++] = res.toDouble();
858
d_data[aux++] = GSL_NAN;
859
qApp->processEvents();
863
QApplication::restoreOverrideCursor();
867
bool MatrixModel::calculate(int startRow, int endRow, int startCol, int endCol)
869
QString formula = d_matrix->formula();
870
if (formula.isEmpty())
873
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
875
ScriptingEnv *scriptEnv = d_matrix->scriptingEnv();
876
Script *script = scriptEnv->newScript(formula, this, QString("<%1>").arg(objectName()));
877
connect(script, SIGNAL(error(const QString&,const QString&,int)), scriptEnv, SIGNAL(error(const QString&,const QString&,int)));
878
connect(script, SIGNAL(print(const QString&)), scriptEnv, SIGNAL(print(const QString&)));
880
if (!script->compile()){
881
QApplication::restoreOverrideCursor();
889
if (endCol >= d_cols)
890
setColumnCount(endCol + 1);
891
if (endRow >= d_rows)
892
setRowCount(endRow + 1);
895
double dx = d_matrix->dx();
896
double dy = d_matrix->dy();
897
double x_start = d_matrix->xStart();
898
double y_start = d_matrix->yStart();
899
double r = 0.0, c = 0.0;
900
for(int row = startRow; row <= endRow; row++){
902
script->setDouble(r, "i");
903
script->setDouble(r, "row");
904
script->setDouble(y_start + row*dy, "y");
905
int aux = row*d_cols + startCol;
906
for(int col = startCol; col <= endCol; col++){
908
script->setDouble(c, "j");
909
script->setDouble(c, "col");
910
script->setDouble(x_start + col*dx, "x");
911
res = script->eval();
912
if (res.canConvert(QVariant::Double))
913
d_data[aux++] = res.toDouble();
915
QApplication::restoreOverrideCursor();
916
d_data[aux++] = GSL_NAN;
920
qApp->processEvents();
923
QApplication::restoreOverrideCursor();
927
void MatrixModel::fft(bool inverse)
932
double **x_int_re = Matrix::allocateMatrixData(height, width); /* real coeff matrix */
935
double **x_int_im = Matrix::allocateMatrixData(height, width); /* imaginary coeff matrix*/
937
Matrix::freeMatrixData(x_int_re, height);
941
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
944
for (int i = 0; i < height; i++){
945
for (int j = 0; j < width; j++){
946
x_int_re[i][j] = d_data[cell++];
947
x_int_im[i][j] = 0.0;
952
double **x_fin_re = Matrix::allocateMatrixData(height, width);
953
double **x_fin_im = Matrix::allocateMatrixData(height, width);
954
if (!x_fin_re || !x_fin_im){
955
Matrix::freeMatrixData(x_int_re, height);
956
Matrix::freeMatrixData(x_int_im, height);
957
QApplication::restoreOverrideCursor();
961
fft2d_inv(x_int_re, x_int_im, x_fin_re, x_fin_im, width, height);
963
for (int i = 0; i < height; i++){
964
for (int j = 0; j < width; j++){
965
double re = x_fin_re[i][j];
966
double im = x_fin_im[i][j];
967
d_data[cell++] = sqrt(re*re + im*im);
970
Matrix::freeMatrixData(x_fin_re, height);
971
Matrix::freeMatrixData(x_fin_im, height);
973
fft2d(x_int_re, x_int_im, width, height);
975
for (int i = 0; i < height; i++){
976
for (int j = 0; j < width; j++){
977
double re = x_int_re[i][j];
978
double im = x_int_im[i][j];
979
d_data[cell++] = sqrt(re*re + im*im);
983
Matrix::freeMatrixData(x_int_re, height);
984
Matrix::freeMatrixData(x_int_im, height);
986
d_matrix->resetView();
987
QApplication::restoreOverrideCursor();
990
void MatrixModel::pasteData(double *clipboardBuffer, int topRow, int leftCol, int rows, int cols)
992
int newCols = leftCol + cols;
993
if (newCols > d_cols)
994
insertColumns(d_cols, newCols - d_cols);
996
int newRows = topRow + rows;
997
if (newRows > d_rows)
998
insertRows(d_rows, newRows - d_rows);
1001
int bottomRow = newRows - 1;
1002
int rightCol = newCols - 1;
1003
for (int i = topRow; i <= bottomRow; i++){
1004
int row = i*d_cols + leftCol;
1005
for (int j = leftCol; j <= rightCol; j++)
1006
d_data[row++] = clipboardBuffer[cell++];