NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
matfuncs.hpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2021 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#ifndef MATFUNCS_HPP
20#define MATFUNCS_HPP
21
22#define EIGENVALUES 0
23#define EIGENVECTORS 1
24#define DIAGONALIZE 2
25
26#include <Eigen/Dense>
27#include <Eigen/Eigenvalues>
28#include <random>
29#include <map>
30#include "matdatastructures.hpp"
31#include "../ui/error.hpp"
32#include "../../kernel.hpp"
34#include "statslogic.hpp"
35
36// Forward declaration from tools.hpp
37std::mt19937& getRandGenInstance();
38
47static inline std::string printMatrixDim(const Matrix& mat)
48{
49 return mat.printDims();
50}
51
52
64static Matrix createFilledMatrix(size_t n, size_t m, const mu::value_type& val)
65{
66 return Matrix(n, m, val);
67}
68
69
80{
81 size_t n = funcData.nVal;
82 size_t m = funcData.mVal;
83
84 if (n && !m)
85 m = n;
86
87 if (!n || !m)
89
90 return createFilledMatrix(n, m, 0.0);
91}
92
93
104{
105 size_t n = funcData.nVal;
106 size_t m = funcData.mVal;
107
108 if (n && !m)
109 m = n;
110
111 if (!n || !m)
113
114 return createFilledMatrix(n, m, 1.0);
115}
116
117
128{
129 if (!funcData.nVal)
131
132 Matrix _mIdentity(funcData.nVal, funcData.nVal, 0.0);
133
134 for (int i = 0; i < funcData.nVal; i++)
135 {
136 _mIdentity(i, i) = 1.0;
137 }
138
139 return _mIdentity;
140}
141
142
153{
154 if (funcData.mat1.isEmpty())
156
157 if (!funcData.mat1.isSquare())
159 printMatrixDim(funcData.mat1));
160
161 Matrix _mReturn(1, 1, 0.0);
162
163 for (unsigned int i = 0; i < funcData.mat1.rows(); i++)
164 {
165 _mReturn(0, 0) += funcData.mat1(i, i);
166 }
167
168 return _mReturn;
169}
170
171
182static mu::value_type calcDeterminant(const Matrix& _mMatrix, std::vector<int> vRemovedLines)
183{
184 // simple Sonderfaelle
185 if (_mMatrix.rows() == 1)
186 return _mMatrix(0, 0);
187
188 if (_mMatrix.rows() == 2)
189 return _mMatrix(0, 0) * _mMatrix(1, 1) - _mMatrix(1, 0)*_mMatrix(0, 1);
190
191 if (_mMatrix.rows() == 3)
192 {
193 return _mMatrix(0, 0)*_mMatrix(1, 1)*_mMatrix(2, 2)
194 + _mMatrix(0, 1)*_mMatrix(1, 2)*_mMatrix(2, 0)
195 + _mMatrix(0, 2)*_mMatrix(1, 0)*_mMatrix(2, 1)
196 - _mMatrix(0, 2)*_mMatrix(1, 1)*_mMatrix(2, 0)
197 - _mMatrix(0, 1)*_mMatrix(1, 0)*_mMatrix(2, 2)
198 - _mMatrix(0, 0)*_mMatrix(1, 2)*_mMatrix(2, 1);
199 }
200
201 int nSign = 1;
202 mu::value_type dDet = 0.0;
203
204 for (unsigned int i = 0; i < _mMatrix.rows(); i++)
205 {
206 // Noch nicht entfernte Zeile?
207 if (!(vRemovedLines[i] & 1))
208 {
209 // entferne Zeile i
210 vRemovedLines[i] += 1;
211
212 for (unsigned int j = 0; j < _mMatrix.rows(); j++)
213 {
214 // Noch nicht entfernte Spalte?
215 if (!(vRemovedLines[j] & 2))
216 {
217 if (_mMatrix(i, j) == 0.0)
218 {
219 nSign *= -1;
220 continue;
221 }
222 // entferne Spalte j
223 vRemovedLines[j] += 2;
224
225 // Berechne Determinante rekursiv
226 if (i+1 < _mMatrix.rows())
227 dDet += (double)nSign * _mMatrix(i, j) * calcDeterminant(_mMatrix, vRemovedLines);
228 else
229 dDet += (double)nSign * _mMatrix(i, j);
230
231 // füge Spalte j wieder hinzu
232 vRemovedLines[j] -= 2;
233 // alternierendes Vorzeichen
234 nSign *= -1;
235 }
236 }
237
238 vRemovedLines[i] -= 1;
239 return dDet;
240 }
241 }
242
243 return 1.0;
244}
245
246
257{
258 if (funcData.mat1.isEmpty())
260
261 if (!funcData.mat1.isSquare())
263 printMatrixDim(funcData.mat1));
264
265 std::vector<int> vRemovedLines(funcData.mat1.rows(), 0);
266 return Matrix(1, 1, calcDeterminant(funcData.mat1, vRemovedLines));
267}
268
269
280{
281 if (funcData.mat1.isEmpty())
283
284 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), 1, 0.0);
285 std::vector<int> vRemovedLines(funcData.mat1.rows(), 0);
286
287 if (funcData.mat1.rows() == 1)
288 return _mResult;
289
290 if (funcData.mat1.rows()-1 != funcData.mat1.cols())
292 printMatrixDim(funcData.mat1));
293
294 if (funcData.mat1.rows() == 2)
295 {
296 _mResult(0) = funcData.mat1(0, 1);
297 _mResult(1) = -funcData.mat1(0, 0);
298 return _mResult;
299 }
300
301 if (funcData.mat1.rows() == 3)
302 {
303 _mResult(0) = funcData.mat1(1, 0)*funcData.mat1(2, 1) - funcData.mat1(2, 0)*funcData.mat1(1, 1);
304 _mResult(1) = funcData.mat1(2, 0)*funcData.mat1(0, 1) - funcData.mat1(0, 0)*funcData.mat1(2, 1);
305 _mResult(2) = funcData.mat1(0, 0)*funcData.mat1(1, 1) - funcData.mat1(1, 0)*funcData.mat1(0, 1);
306 return _mResult;
307 }
308
309 Matrix _mTemp = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols()+1, 0.0);
310
311 #pragma omp parallel for
312 for (unsigned int i = 0; i < funcData.mat1.rows(); i++)
313 {
314 for (unsigned int j = 0; j < funcData.mat1.cols(); j++)
315 {
316 _mTemp(i, j+1) = funcData.mat1(i, j);
317 }
318 }
319
320 _mTemp(0, 0) = 1.0;
321 _mResult(0, 0) = calcDeterminant(_mTemp, vRemovedLines);
322
323 for (unsigned int i = 1; i < funcData.mat1.rows(); i++)
324 {
325 _mTemp(i-1, 0) = 0.0;
326 _mTemp(i, 0) = 1.0;
327 _mResult(i, 0) = calcDeterminant(_mTemp, vRemovedLines);
328 }
329
330 return _mResult;
331}
332
333
357__attribute__((force_align_arg_pointer)) static Matrix calcEigenVectsAndValues(const Matrix& _mMatrix, int nReturnType, const MatFuncErrorInfo& errorInfo)
358{
359 if (_mMatrix.isEmpty())
361
362 if (!_mMatrix.isSquare())
364 printMatrixDim(_mMatrix));
365
366 if (_mMatrix.containsInvalidValues())
368
371
372 Eigen::MatrixXcd mMatrix(_mMatrix.rows(), _mMatrix.rows());
373
374 // Copy the passed matrix into an Eigen matrix
375 #pragma omp parallel for
376 for (unsigned int i = 0; i < _mMatrix.rows(); i++)
377 {
378 for (unsigned int j = 0; j < _mMatrix.rows(); j++)
379 {
380 mMatrix(i,j) = _mMatrix(i,j);
381 }
382 }
383
384 // Construct an Eigen eigenvalue solver
385 Eigen::ComplexEigenSolver<Eigen::MatrixXcd> eSolver(mMatrix);
386
387 // Get eigenvalues, eigenvectors or the diagonal matrix depending
388 // on the selected return type. Separate the result into real and
389 // imaginary parts
391 {
392 Eigen::VectorXcd vEigenVals = eSolver.eigenvalues();
393 _mEigenVals.resize(_mMatrix.rows(), 1);
394
395 for (unsigned int i = 0; i < _mEigenVals.rows(); i++)
396 {
397 _mEigenVals(i) = vEigenVals(i, 0);
398 }
399 }
400 else if (nReturnType == EIGENVECTORS)
401 {
402 Eigen::EigenSolver<Eigen::MatrixXcd>::EigenvectorsType mEigenVects = eSolver.eigenvectors();
403 _mEigenVects.resize(_mMatrix.rows(), _mMatrix.cols());
404
405 #pragma omp parallel for
406 for (unsigned int i = 0; i < _mEigenVects.rows(); i++)
407 {
408 for (unsigned int j = 0; j < _mEigenVects.cols(); j++)
409 {
410 _mEigenVects(i, j) = mEigenVects(i, j);
411 }
412 }
413 }
414 else if (nReturnType == DIAGONALIZE)
415 {
416 Eigen::VectorXcd vEigenVals = eSolver.eigenvalues();
417 _mEigenVects.resize(_mMatrix.rows(), _mMatrix.cols());
418
419 for (unsigned int i = 0; i < _mEigenVects.rows(); i++)
420 {
421 _mEigenVects(i, i) = vEigenVals(i, 0);
422 }
423 }
424
425 // Return the corresponding result
427 return _mEigenVals;
428 else
429 return _mEigenVects;
430}
431
432
443{
444 return calcEigenVectsAndValues(funcData.mat1, EIGENVECTORS, errorInfo);
445}
446
447
458{
459 return calcEigenVectsAndValues(funcData.mat1, EIGENVALUES, errorInfo);
460}
461
462
473{
474 return calcEigenVectsAndValues(funcData.mat1, DIAGONALIZE, errorInfo);
475}
476
477
489{
490 unsigned int nShuffle = funcData.nVal;
491 unsigned int nBase = funcData.mVal;
492
493 if (!nBase && nShuffle)
494 nBase = nShuffle;
495
496 if (!nBase)
498
499 Matrix _mBase = createFilledMatrix(nBase, 1, 0.0);
500
501 if (nShuffle > nBase)
502 nShuffle = nBase;
503
504 // Create the base (unshuffled) vector
505 for (size_t i = 0; i < nBase; i++)
506 _mBase(i) = i+1;
507
508 // Shuffle the vector by swapping the i-th shuffled
509 // element with the i-th element
510 for (size_t i = 0; i < nShuffle; i++)
511 {
512 std::uniform_real_distribution<double> randDist(i, nBase-1);
513
514 int nIndex = rint(randDist(getRandGenInstance()));
515 mu::value_type dTemp = _mBase(i);
516 _mBase(i) = _mBase(nIndex);
517 _mBase(nIndex) = dTemp;
518 }
519
520 // Return only the requested vector length
521 _mBase.resize(nShuffle, 1);
522 return _mBase;
523}
524
525
537{
538 if (funcData.mat1.isEmpty())
540
541 if (!funcData.mat1.isSquare())
543 printMatrixDim(funcData.mat1));
544
545 if (funcData.mat1.containsInvalidValues())
547
548 // Gauss-Elimination???
549 Matrix _mInverse = identityMatrix(MatFuncData(funcData.mat1.rows()), errorInfo);
550 Matrix _mToInvert = funcData.mat1;
551
552 mu::value_type dDet = getDeterminant(funcData, errorInfo)(0);
553
554 if (dDet == 0.0)
556
557 //Spezialfaelle mit analytischem Ausdruck
558 if (_mToInvert.rows() == 1)
559 {
560 // eigentlich nicht zwangslaeufig existent... aber skalar und so...
561 _mInverse(0) /= _mToInvert(0);
562 return _mInverse;
563 }
564 else if (_mToInvert.rows() == 2)
565 {
566 _mInverse = _mToInvert;
567 _mInverse(0, 0) = _mToInvert(1, 1);
568 _mInverse(1, 1) = _mToInvert(0, 0);
569 _mInverse(1, 0) *= -1.0;
570 _mInverse(0, 1) *= -1.0;
571
572 for (unsigned int i = 0; i < 2; i++)
573 {
574 _mInverse(i, 0) /= dDet;
575 _mInverse(i, 1) /= dDet;
576 }
577
578 return _mInverse;
579 }
580 else if (_mToInvert.rows() == 3)
581 {
582 _mInverse(0, 0) = (_mToInvert(1, 1)*_mToInvert(2, 2) - _mToInvert(2, 1)*_mToInvert(1, 2)) / dDet;
583 _mInverse(1, 0) = -(_mToInvert(1, 0)*_mToInvert(2, 2) - _mToInvert(1, 2)*_mToInvert(2, 0)) / dDet;
584 _mInverse(2, 0) = (_mToInvert(1, 0)*_mToInvert(2, 1) - _mToInvert(1, 1)*_mToInvert(2, 0)) / dDet;
585
586 _mInverse(0, 1) = -(_mToInvert(0, 1)*_mToInvert(2, 2) - _mToInvert(0, 2)*_mToInvert(2, 1)) / dDet;
587 _mInverse(1, 1) = (_mToInvert(0, 0)*_mToInvert(2, 2) - _mToInvert(0, 2)*_mToInvert(2, 0)) / dDet;
588 _mInverse(2, 1) = -(_mToInvert(0, 0)*_mToInvert(2, 1) - _mToInvert(0, 1)*_mToInvert(2, 0)) / dDet;
589
590 _mInverse(0, 2) = (_mToInvert(0, 1)*_mToInvert(1, 2) - _mToInvert(0, 2)*_mToInvert(1, 1)) / dDet;
591 _mInverse(1, 2) = -(_mToInvert(0, 0)*_mToInvert(1, 2) - _mToInvert(0, 2)*_mToInvert(1, 0)) / dDet;
592 _mInverse(2, 2) = (_mToInvert(0, 0)*_mToInvert(1, 1) - _mToInvert(0, 1)*_mToInvert(1, 0)) / dDet;
593
594 return _mInverse;
595 }
596
597 // Allgemeiner Fall fuer n > 3
598 for (unsigned int j = 0; j < _mToInvert.cols(); j++)
599 {
600 for (unsigned int i = j; i < _mToInvert.rows(); i++)
601 {
602 if (_mToInvert(i, j) != 0.0)
603 {
604 if (i != j) //vertauschen
605 {
606 mu::value_type dElement;
607
608 for (unsigned int _j = 0; _j < _mToInvert.cols(); _j++)
609 {
610 dElement = _mToInvert(i, _j);
611 _mToInvert(i, _j) = _mToInvert(j, _j);
612 _mToInvert(j, _j) = dElement;
613 dElement = _mInverse(i, _j);
614 _mInverse(i, _j) = _mInverse(j, _j);
615 _mInverse(j, _j) = dElement;
616 }
617
618 i = j-1;
619 }
620 else //Gauss-Elimination
621 {
622 mu::value_type dPivot = _mToInvert(i, j);
623
624 for (unsigned int _j = 0; _j < _mToInvert.cols(); _j++)
625 {
626 _mToInvert(i, _j) /= dPivot;
627 _mInverse(i, _j) /= dPivot;
628 }
629
630 for (unsigned int _i = i+1; _i < _mToInvert.rows(); _i++)
631 {
632 mu::value_type dFactor = _mToInvert(_i, j);
633
634 if (dFactor == 0.0) // Bereits 0???
635 continue;
636
637 for (unsigned int _j = 0; _j < _mToInvert.cols(); _j++)
638 {
639 _mToInvert(_i, _j) -= _mToInvert(i, _j)*dFactor;
640 _mInverse(_i, _j) -= _mInverse(i, _j)*dFactor;
641 }
642 }
643
644 break;
645 }
646 }
647 }
648 }
649
650 // die Matrix _mToInvert() sollte nun Dreiecksgestalt besitzen. Jetzt den Gauss von unten her umkehren
651 for (int j = (int)_mToInvert.rows()-1; j >= 0; j--)
652 {
653 if (_mToInvert(j, j) == 0.0) // Hauptdiagonale ist ein Element == 0??
655
656 if (_mToInvert(j, j) != 1.0)
657 {
658 for (unsigned int _j = 0; _j < _mInverse.cols(); _j++)
659 _mInverse(j, _j) /= _mToInvert(j, j);
660
661 _mToInvert(j, j) = 1.0;
662 }
663
664 for (int i = 0; i < j; i++)
665 {
666 for (unsigned int _j = 0; _j < _mInverse.cols(); _j++)
667 _mInverse(i, _j) -= _mToInvert(i, j)*_mInverse(j, _j);
668
669 _mToInvert(i, j) -= _mToInvert(i, j)*_mToInvert(j, j);
670 }
671 }
672
673 return _mInverse;
674}
675
676
687{
688 Matrix _mTransposed(funcData.mat1);
689 _mTransposed.transpose();
690 return _mTransposed;
691}
692
693
704{
705 if (funcData.mat1.isEmpty())
707
708 std::vector<double> vLines;
709 std::vector<double> vRows;
710
711 if (funcData.mat1.rows() == 1 || funcData.mat1.cols() == 1)
712 {
713 for (size_t i = 0; i < funcData.mat1.rows(); i++)
714 {
715 for (size_t j = 0; j < funcData.mat1.cols(); j++)
716 {
717 if (funcData.mat1(i, j).real())
718 vLines.push_back(i + j + 1);
719 }
720 }
721
722 if (!vLines.size())
723 return createFilledMatrix(1, 1, 0.0);
724
725 Matrix _mReturn = createFilledMatrix(vLines.size(), 1, 0.0);
726
727 for (size_t i = 0; i < vLines.size(); i++)
728 _mReturn(i) = vLines[i];
729
730 return _mReturn;
731 }
732 else
733 {
734 for (size_t i = 0; i < funcData.mat1.rows(); i++)
735 {
736 for (size_t j = 0; j < funcData.mat1.cols(); j++)
737 {
738 if (funcData.mat1(i, j).real())
739 {
740 vLines.push_back(i+1);
741 vRows.push_back(j+1);
742 }
743 }
744 }
745
746 if (!vLines.size())
747 return createFilledMatrix(1, 1, 0.0);
748
749 Matrix _mReturn = createFilledMatrix(vLines.size(), 2, 0.0);
750
751 for (size_t i = 0; i < vLines.size(); i++)
752 {
753 _mReturn(i, 0) = vLines[i];
754 _mReturn(i, 1) = vRows[i];
755 }
756
757 return _mReturn;
758 }
759}
760
761
778static mu::value_type calculateStats(const Matrix& mat, StatsLogic logic, int rowStart, size_t rowCount, int colStart, size_t colCount)
779{
780 constexpr size_t MINTHREADCOUNT = 100;
781 constexpr size_t MINELEMENTPERCOL = 100;
782
783 std::vector<StatsLogic> operation(rowCount, logic);
784
785 // Only apply multiprocessing, if there are really a lot of
786 // elements to process
787 if (rowCount >= MINTHREADCOUNT && colCount >= MINELEMENTPERCOL)
788 {
789 #pragma omp parallel for
790 for (size_t i = 0; i < rowCount; i++)
791 {
792 if (rowStart + (int)i < 0 || rowStart + i >= mat.rows())
793 continue;
794
795 for (size_t j = 0; j < colCount; j++)
796 {
797 if (colStart + (int)j < 0 || colStart + j >= mat.cols())
798 continue;
799
800 operation[i](mat(i+rowStart, j+colStart));
801 }
802 }
803 }
804 else
805 {
806 for (size_t i = 0; i < rowCount; i++)
807 {
808 if (rowStart + (int)i < 0 || rowStart + i >= mat.rows())
809 continue;
810
811 for (size_t j = 0; j < colCount; j++)
812 {
813 if (colStart + (int)j < 0 || colStart + j >= mat.cols())
814 continue;
815
816 operation[i](mat(i+rowStart, j+colStart));
817 }
818 }
819 }
820
821 for (size_t i = 1; i < operation.size(); i++)
822 {
823 operation.front().combine(operation[i]);
824 }
825
826 return operation.front().m_val;
827}
828
829
840{
841 if (funcData.mat1.isEmpty())
843
844 return createFilledMatrix(1, 1, calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MAX, funcData.mat1(0).real()),
845 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
846}
847
848
859{
860 if (funcData.mat1.isEmpty())
862
863 if (funcData.nVal < 0 || funcData.mVal < 0
864 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
866
867 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
868
869 #pragma omp parallel for
870 for (int i = 0; i < (int)_mResult.rows(); i++)
871 {
872 for (int j = 0; j < (int)_mResult.cols(); j++)
873 {
874 if (!isnan(funcData.mat1(i, j)))
875 _mResult(i, j) = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MAX, funcData.mat1(i, j).real()),
876 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
877 }
878 }
879
880 return _mResult;
881}
882
883
894{
895 if (funcData.mat1.isEmpty())
897
898 if (funcData.mat1.rows() == 1 || funcData.mat1.cols() == 1)
899 {
900 Matrix _mMatrixMax = matrixMax(funcData, errorInfo);
901
902 if (!_mMatrixMax(0).real() || _mMatrixMax(0).real() < 0)
903 return createFilledMatrix(1, 1, 0.0);
904
905 Matrix _mReturn = createFilledMatrix(_mMatrixMax(0).real(), 1, 0.0);
906
907 for (size_t i = 0; i < funcData.mat1.rows(); i++)
908 {
909 for (size_t j = 0; j < funcData.mat1.cols(); j++)
910 {
911 if (funcData.mat1(i, j).real() > 0)
912 _mReturn(funcData.mat1(i, j).real()-1) = 1.0;
913 }
914 }
915
916 return _mReturn;
917 }
918 else
919 {
920 std::vector<double> vCol;
921 std::vector<double> vRow;
922
923 if (funcData.mat1.rows() == 2 && funcData.mat1.cols() != 2)
924 {
925 for (size_t i = 0; i < funcData.mat1.cols(); i++)
926 {
927 vRow.push_back(funcData.mat1(0, i).real());
928 vCol.push_back(funcData.mat1(1, i).real());
929 }
930 }
931 else if (funcData.mat1.rows() != 2 && funcData.mat1.cols() == 2)
932 {
933 for (size_t i = 0; i < funcData.mat1.rows(); i++)
934 {
935 vRow.push_back(funcData.mat1(i, 0).real());
936 vCol.push_back(funcData.mat1(i, 1).real());
937 }
938 }
939 else
940 return createFilledMatrix(1, 1, 0.0);
941
942 int nRowMax = 0;
943 int nColMax = 0;
944
945 for (size_t i = 0; i < vRow.size(); i++)
946 {
947 if (nRowMax < (int)vRow[i])
948 nRowMax = (int)vRow[i];
949
950 if (nColMax < (int)vCol[i])
951 nColMax = (int)vCol[i];
952 }
953
954 if (!nColMax || !nRowMax)
955 return createFilledMatrix(1, 1, 0.0);
956
957 Matrix _mReturn = createFilledMatrix(nRowMax, nColMax, 0.0);
958
959 for (size_t i = 0; i < vRow.size(); i++)
960 {
961 if (vRow[i] > 0 && vCol[i] > 0)
962 _mReturn(vRow[i]-1, vCol[i]-1) = 1.0;
963 }
964
965 return _mReturn;
966 }
967}
968
969
980{
981 if (funcData.mat1.isEmpty())
983
984 Matrix _mReturn = createFilledMatrix(2, 1, 0.0);
985
986 if (funcData.mat1.rows() == 1 && funcData.mat1.cols() == 1 && isnan(funcData.mat1(0)))
987 return _mReturn;
988
989 _mReturn(0) = funcData.mat1.rows();
990 _mReturn(1) = funcData.mat1.cols();
991
992 return _mReturn;
993}
994
995
1006{
1007 if (funcData.mat1.isEmpty())
1009
1010 for (size_t i = 0; i < funcData.mat1.rows(); i++)
1011 {
1012 for (size_t j = 0; j < funcData.mat1.cols(); j++)
1013 {
1014 if (funcData.mat1(i, j) == 0.0)
1015 return createFilledMatrix(1, 1, 0.0);
1016 }
1017 }
1018
1019 return createFilledMatrix(1, 1, 1.0);
1020}
1021
1022
1033{
1034 if (funcData.mat1.isEmpty())
1036
1037 for (size_t i = 0; i < funcData.mat1.rows(); i++)
1038 {
1039 for (size_t j = 0; j < funcData.mat1.cols(); j++)
1040 {
1041 if (funcData.mat1(i, j) != 0.0)
1042 return createFilledMatrix(1, 1, 1.0);
1043 }
1044 }
1045
1046 return createFilledMatrix(1, 1, 0.0);
1047}
1048
1049
1060{
1061 if (funcData.mat1.isEmpty())
1063
1064 bool isTrue = false;
1065
1066 for (size_t i = 0; i < funcData.mat1.rows(); i++)
1067 {
1068 for (size_t j = 0; j < funcData.mat1.cols(); j++)
1069 {
1070 if (funcData.mat1(i, j) != 0.0)
1071 {
1072 if (!isTrue)
1073 isTrue = true;
1074 else
1075 return createFilledMatrix(1, 1, 0.0);
1076 }
1077 }
1078 }
1079
1080 if (isTrue)
1081 return createFilledMatrix(1, 1, 1.0);
1082
1083 return createFilledMatrix(1, 1, 0.0);
1084}
1085
1086
1097{
1098 if (funcData.mat1.isEmpty())
1100
1102 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1103}
1104
1105
1116{
1117 if (funcData.mat1.isEmpty())
1119
1120 if (funcData.nVal < 0 || funcData.mVal < 0
1121 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1123
1124 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1125
1126 #pragma omp parallel for
1127 for (int i = 0; i < (int)_mResult.rows(); i++)
1128 {
1129 for (int j = 0; j < (int)_mResult.cols(); j++)
1130 {
1131 if (!isnan(funcData.mat1(i, j)))
1132 _mResult(i, j) = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_ADD),
1133 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1134 }
1135 }
1136
1137 return _mResult;
1138}
1139
1140
1151{
1152 if (funcData.mat1.isEmpty())
1154
1156 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1157}
1158
1159
1170{
1171 if (funcData.mat1.isEmpty())
1173
1174 if (funcData.nVal < 0 || funcData.mVal < 0
1175 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1177
1178 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1179
1180 #pragma omp parallel for
1181 for (int i = 0; i < (int)_mResult.rows(); i++)
1182 {
1183 for (int j = 0; j < (int)_mResult.cols(); j++)
1184 {
1185 if (!isnan(funcData.mat1(i, j)))
1186 _mResult(i, j) = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_NUM),
1187 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1188 }
1189 }
1190
1191 return _mResult;
1192}
1193
1194
1205{
1206 if (funcData.mat1.isEmpty())
1208
1209 Matrix _mSum = matrixSum(funcData, errorInfo);
1210 Matrix _mNum = matrixNum(funcData, errorInfo);
1211
1212 return createFilledMatrix(1, 1, _mSum(0) / _mNum(0));
1213}
1214
1215
1226{
1227 if (funcData.mat1.isEmpty())
1229
1230 if (funcData.nVal < 0 || funcData.mVal < 0
1231 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1233
1234 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1235
1236 #pragma omp parallel for
1237 for (int i = 0; i < (int)_mResult.rows(); i++)
1238 {
1239 for (int j = 0; j < (int)_mResult.cols(); j++)
1240 {
1241 if (!isnan(funcData.mat1(i, j)))
1242 {
1244 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1245
1247 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1).real();
1248
1249 if (num > 0)
1250 _mResult(i, j) = sum / num;
1251 }
1252 }
1253 }
1254
1255 return _mResult;
1256}
1257
1258
1269{
1270 if (funcData.mat1.isEmpty())
1272
1273 Matrix _mAvg = matrixAvg(funcData, errorInfo);
1274 Matrix _mNum = matrixNum(funcData, errorInfo);
1275 Matrix _mReturn = createFilledMatrix(1, 1, calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_ADDSQSUB, 0.0, _mAvg(0)),
1276 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1277
1278 _mReturn(0) = std::sqrt(_mReturn(0)/(_mNum(0).real()-1.0));
1279 return _mReturn;
1280}
1281
1282
1293{
1294 if (funcData.mat1.isEmpty())
1296
1297 if (funcData.nVal < 0 || funcData.mVal < 0
1298 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1300
1301 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1302
1303 #pragma omp parallel for
1304 for (int i = 0; i < (int)_mResult.rows(); i++)
1305 {
1306 for (int j = 0; j < (int)_mResult.cols(); j++)
1307 {
1308 if (!isnan(funcData.mat1(i, j)))
1309 {
1311 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1312
1314 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1).real();
1315
1317 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1318
1319 if (num > 1)
1320 _mResult(i, j) = std::sqrt(std / (num - 1.0));
1321 }
1322 }
1323 }
1324
1325 return _mResult;
1326}
1327
1328
1339{
1340 if (funcData.mat1.isEmpty())
1342
1344 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1345}
1346
1347
1358{
1359 if (funcData.mat1.isEmpty())
1361
1362 if (funcData.nVal < 0 || funcData.mVal < 0
1363 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1365
1366 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1367
1368 #pragma omp parallel for
1369 for (int i = 0; i < (int)_mResult.rows(); i++)
1370 {
1371 for (int j = 0; j < (int)_mResult.cols(); j++)
1372 {
1373 if (!isnan(funcData.mat1(i, j)))
1374 _mResult(i, j) = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MULT, 1.0),
1375 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1376 }
1377 }
1378
1379 return _mResult;
1380}
1381
1382
1393{
1394 if (funcData.mat1.isEmpty())
1396
1397 return createFilledMatrix(1, 1, funcData.mat1.rows() * funcData.mat1.cols());
1398}
1399
1400
1412{
1413 // Define the thresholds
1414 double thresHigh(NAN);
1415 double thresLow(NAN);
1416
1417 // Get the input values
1418 double thresInput = funcData.fVal.real();
1419 int mode = funcData.nVal;
1420
1421 // Check if the mode is within the acceptable range
1422 if(std::abs(mode) > 2)
1424
1425 // Get the min and max values of the matrix for the threshold calculation
1426 double matMin = 0;
1427 double matMax = 0;
1428
1429 // If necessary get the min and max values of the matrices
1430 if(std::abs(mode) < 2)
1431 {
1432 matMin = real(calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MIN, funcData.mat1(0).real()),
1433 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1434 matMax = real(calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MAX, funcData.mat1(0).real()),
1435 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1436 }
1437
1438 // Set the thresholds and the data to insert
1439 switch(mode)
1440 {
1441 case -2:
1442 // Absolut value, cut all values below
1443 {
1444 thresHigh = NAN;
1445 thresLow = thresInput;
1446 }
1447 break;
1448 case 2:
1449 // Absolut value, cut all values above
1450 {
1451 thresHigh = thresInput;
1452 thresLow = NAN;
1453 }
1454 break;
1455 case 1:
1456 // Percentage value, cut all values above
1457 {
1458 thresHigh = matMin + (matMax - matMin) * thresInput;
1459 thresLow = NAN;
1460 }
1461 break;
1462 case -1:
1463 // Percentage value, cut all values below
1464 {
1465 thresHigh = NAN;
1466 thresLow = matMin + (matMax - matMin) * thresInput;
1467 }
1468 break;
1469 case 0:
1470 // Central percent of values
1471 {
1472 thresHigh = matMin + (matMax - matMin) / 2 + (matMax - matMin) * thresInput / 2.0;
1473 thresLow = matMin + (matMax - matMin) / 2 - (matMax - matMin) * thresInput / 2.0;
1474 }
1475 break;
1476 }
1477
1478 // Get a copy of the matrix to process
1479 Matrix cutMatrix = funcData.mat1;
1480
1481 // Apply the calculated threshold to all matrix elements
1482 for (size_t i = 0; i < cutMatrix.rows(); i++)
1483 {
1484 for (size_t j = 0; j < cutMatrix.cols(); j++)
1485 {
1486 // Only the real part is considered, imaginary component is discarded
1487 if(!std::isnan(thresLow) && cutMatrix(i, j).real() < thresLow)
1488 cutMatrix(i, j) = thresLow;
1489 if(!std::isnan(thresHigh) && cutMatrix(i, j).real() > thresHigh)
1490 cutMatrix(i, j) = thresHigh;
1491 }
1492 }
1493
1494 return cutMatrix;
1495}
1496
1497
1508{
1509 if (funcData.mat1.isEmpty())
1511
1513 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1514
1515 _mReturn(0) = std::sqrt(_mReturn(0));
1516 return _mReturn;
1517}
1518
1519
1530{
1531 if (funcData.mat1.isEmpty())
1533
1534 if (funcData.nVal < 0 || funcData.mVal < 0
1535 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1537
1538 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1539
1540 #pragma omp parallel for
1541 for (int i = 0; i < (int)_mResult.rows(); i++)
1542 {
1543 for (int j = 0; j < (int)_mResult.cols(); j++)
1544 {
1545 if (!isnan(funcData.mat1(i, j)))
1546 _mResult(i, j) = std::sqrt(calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_ADDSQ),
1547 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1));
1548 }
1549 }
1550
1551 return _mResult;
1552}
1553
1554
1565{
1566 if (funcData.mat1.isEmpty())
1568
1569 return createFilledMatrix(1, 1, calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MIN, funcData.mat1(0).real()),
1570 0, funcData.mat1.rows(), 0, funcData.mat1.cols()));
1571}
1572
1573
1584{
1585 if (funcData.mat1.isEmpty())
1587
1588 if (funcData.nVal < 0 || funcData.mVal < 0
1589 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1591
1592 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1593
1594 #pragma omp parallel for
1595 for (int i = 0; i < (int)_mResult.rows(); i++)
1596 {
1597 for (int j = 0; j < (int)_mResult.cols(); j++)
1598 {
1599 if (!isnan(funcData.mat1(i, j)))
1600 _mResult(i, j) = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MIN, funcData.mat1(i, j).real()),
1601 i-funcData.nVal, 2*funcData.nVal+1, j-funcData.mVal, 2*funcData.mVal+1);
1602 }
1603 }
1604
1605 return _mResult;
1606}
1607
1608
1619{
1620 if (funcData.mat1.isEmpty())
1622
1623 Matrix _mReturn = createFilledMatrix(1, 1, 0.0);
1624 Matrix _mCoords = createFilledMatrix(2, 1, 0.0);
1625 _mCoords(0) = -1;
1626
1627 mu::value_type dValue = funcData.fVal;
1628 int nType = funcData.nVal;
1629 mu::value_type dKeep = dValue;
1630
1631 for (size_t i = 0; i < funcData.mat1.rows(); i++)
1632 {
1633 for (size_t j = 0; j < funcData.mat1.cols(); j++)
1634 {
1635 if (isnan(funcData.mat1(i, j)) || isinf(funcData.mat1(i, j)))
1636 continue;
1637
1638 if (funcData.mat1(i, j) == dValue)
1639 {
1640 if (!nType || abs(nType) <= 1)
1641 {
1642 _mCoords(0) = i+1;
1643 _mCoords(1) = j+1;
1644 return _mCoords;
1645 }
1646 else
1647 _mReturn(0) = funcData.mat1(i, j);
1648
1649 return _mReturn;
1650 }
1651 else if (nType > 0 && funcData.mat1(i, j).real() > dValue.real())
1652 {
1653 if (_mCoords(0) == -1.0 || funcData.mat1(i, j).real() < dKeep.real())
1654 {
1655 dKeep = funcData.mat1(i, j).real();
1656 _mCoords(0) = i+1;
1657 _mCoords(1) = j+1;
1658 }
1659 else
1660 continue;
1661 }
1662 else if (nType < 0 && funcData.mat1(i, j).real() < dValue.real())
1663 {
1664 if (_mCoords(0) == -1.0 || funcData.mat1(i, j).real() > dKeep.real())
1665 {
1666 dKeep = funcData.mat1(i, j).real();
1667 _mCoords(0) = i+1;
1668 _mCoords(1) = j+1;
1669 }
1670 else
1671 continue;
1672 }
1673 }
1674 }
1675
1676 if (_mCoords(0) == -1.0)
1677 _mReturn(0) = NAN;
1678 else if (nType <= -2 || nType >= 2)
1679 _mReturn(0) = dKeep;
1680 else
1681 {
1682 return _mCoords;
1683 }
1684
1685 return _mReturn;
1686}
1687
1688
1699{
1700 if (funcData.mat1.isEmpty())
1702
1703 return matrixCmp(MatFuncData(funcData.mat1, matrixMin(funcData, errorInfo)(0), 0), errorInfo);
1704}
1705
1706
1717{
1718 if (funcData.mat1.isEmpty())
1720
1721 return matrixCmp(MatFuncData(funcData.mat1, matrixMax(funcData, errorInfo)(0), 0), errorInfo);
1722}
1723
1724
1735{
1736 if (funcData.mat1.isEmpty())
1738
1739 Memory _mem;
1740 size_t nElems = funcData.mat1.data().size();
1741
1742 // Preallocate
1743 _mem.writeData(nElems-1, 0, 0.0);
1744
1745 //#pragma omp parallel for
1746 for (size_t i = 0; i < nElems; i++)
1747 {
1748 _mem.writeDataDirectUnsafe(i, 0, funcData.mat1.data()[i]);
1749 }
1750
1751 return createFilledMatrix(1, 1, _mem.med(VectorIndex(0, funcData.mat1.rows()*funcData.mat1.cols()-1), VectorIndex(0)));
1752}
1753
1754
1765{
1766 if (funcData.mat1.isEmpty())
1768
1769 if (funcData.nVal < 0 || funcData.mVal < 0
1770 || 2*funcData.nVal+1 > (int)funcData.mat1.rows() || 2*funcData.mVal+1 > (int)funcData.mat1.cols())
1772
1773 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
1774
1775 #pragma omp parallel for
1776 for (int i = 0; i < (int)_mResult.rows(); i++)
1777 {
1778 for (int j = 0; j < (int)_mResult.cols(); j++)
1779 {
1780 if (!isnan(funcData.mat1(i, j)))
1781 {
1782 Memory _mem;
1783
1784 for (int n = 0; n < 2*funcData.nVal+1; n++)
1785 {
1786 if (i+n-funcData.nVal < 0 || i+n-funcData.nVal >= (int)funcData.mat1.rows())
1787 continue;
1788
1789 for (int m = 0; m < 2*funcData.mVal+1; m++)
1790 {
1791 if (j+m-funcData.mVal < 0 || j+m-funcData.mVal >= (int)funcData.mat1.cols())
1792 continue;
1793
1794 _mem.writeData(m + n*(2*funcData.mVal+1), 0, funcData.mat1(i+n-funcData.nVal, j+m-funcData.mVal));
1795 }
1796 }
1797
1798 _mResult(i, j) = _mem.med(VectorIndex(0, (2*funcData.nVal+1)*(2*funcData.mVal+1)), VectorIndex(0));
1799 }
1800 }
1801 }
1802
1803 return _mResult;
1804}
1805
1806
1817{
1818 if (funcData.mat1.isEmpty())
1820
1821 Memory _mem;
1822 size_t nElems = funcData.mat1.data().size();
1823
1824 // Preallocate
1825 _mem.writeData(nElems-1, 0, 0.0);
1826
1827 //#pragma omp parallel for
1828 for (size_t i = 0; i < nElems; i++)
1829 {
1830 _mem.writeDataDirectUnsafe(i, 0, funcData.mat1.data()[i]);
1831 }
1832
1833 return createFilledMatrix(1, 1, _mem.pct(VectorIndex(0, (long long int)(funcData.mat1.rows()*funcData.mat1.cols())-1), VectorIndex(0), funcData.fVal));
1834}
1835
1836
1848{
1849 size_t nLines = funcData.fVal.real();
1850 size_t nCols = funcData.nVal;
1851
1852 if (funcData.mat1.isEmpty() || !nLines || !nCols)
1854
1855 if (nLines == funcData.mat1.rows() && nCols == funcData.mat1.cols())
1856 return funcData.mat1;
1857
1858 Matrix _mReturn(funcData.mat1);
1859 _mReturn.resize(nLines, nCols);
1860
1861 return _mReturn;
1862}
1863
1864
1878{
1879 if (funcData.mat1.isEmpty() || funcData.mat2.isEmpty())
1881
1882 // Ensure that the size is non-zero
1883 if (!(funcData.mat1.rows() && funcData.mat2.rows()) || !(funcData.mat1.cols() && funcData.mat2.cols()))
1885 printMatrixDim(funcData.mat1) + ", " + printMatrixDim(funcData.mat2));
1886
1887 int n = std::max(funcData.mat1.rows(), funcData.mat2.rows());
1888 int m = std::max(funcData.mat1.cols(), funcData.mat2.cols());
1889
1890 // Resize the matrices to fit their counterparts
1891 Matrix mMatrix1(funcData.mat1);
1892 mMatrix1.resize(n, m);
1893
1894 Matrix mMatrix2(funcData.mat2);
1895 mMatrix2.resize(n, m);
1896
1897 // Create the target matrix
1898 Matrix mCorrelation = createFilledMatrix(2*n-1, 2*m-1, 0.0);
1899
1900 // Calculate the elements of the matrix by applying
1901 // elementwise shifts to the matrices
1902 #pragma omp parallel for
1903 for (int i1 = 0; i1 < (int)mCorrelation.rows(); i1++)
1904 {
1905 for (int j1 = 0; j1 < (int)mCorrelation.cols(); j1++)
1906 {
1907 // These loops shall indicate the number of elements
1908 for (int i2 = 0; i2 < n + std::min(i1-n+1, n-i1-1); i2++)
1909 {
1910 for (int j2 = 0; j2 < m + std::min(j1-m+1, m-j1-1); j2++)
1911 {
1912 // calculate the correlation of the current
1913 // shift indicated by the other two loops
1914 mCorrelation(i1, j1) += mMatrix1(i2 + std::max(0, i1-n+1), j2 + std::max(0, j1-m+1))
1915 * mMatrix2(i2 + std::max(0, n-i1-1), j2 + std::max(0, m-j1-1));
1916 }
1917 }
1918 }
1919 }
1920
1921 return mCorrelation;
1922}
1923
1924
1936{
1937 if (funcData.mat1.isEmpty() || funcData.mat2.isEmpty())
1939
1940 // Ensure that their size is equal
1941 if (funcData.mat1.rows() != funcData.mat2.rows() || funcData.mat1.cols() != funcData.mat2.cols())
1943 printMatrixDim(funcData.mat1) + " != " + printMatrixDim(funcData.mat2));
1944
1945 // Prepare the target matrix
1946 Matrix mCovariance = createFilledMatrix(1, 1, 0.0);
1947
1948 // Calculate the average values of both
1949 // matrices
1950 Matrix mAvg1 = matrixAvg(MatFuncData(funcData.mat1), errorInfo);
1951 Matrix mAvg2 = matrixAvg(MatFuncData(funcData.mat2), errorInfo);
1952
1953 // Calculate the covariance value for each
1954 // component and sum it up
1955 for (size_t i = 0; i < funcData.mat1.rows(); i++)
1956 {
1957 for (size_t j = 0; j < funcData.mat1.cols(); j++)
1958 {
1959 mCovariance(0) += (funcData.mat1(i, j) - mAvg1(0)) * (funcData.mat2(i, j) - mAvg2(0));
1960 }
1961 }
1962
1963 // Normalize the covariance value using
1964 // the number of elements
1965 mCovariance(0) /= (funcData.mat1.rows() * funcData.mat1.cols() - 1);
1966
1967 return mCovariance;
1968}
1969
1970
1983{
1984 if (funcData.mat1.isEmpty())
1986
1987 Matrix _mReturn = funcData.mat1;
1988 Matrix _mMax = matrixMax(funcData, errorInfo);
1989 Matrix _mMin = matrixMin(funcData, errorInfo);
1990
1991 double dMax = std::max(fabs(_mMax(0)), fabs(_mMin(0)));
1992
1993 #pragma omp parallel for
1994 for (size_t i = 0; i < _mReturn.rows(); i++)
1995 {
1996 for (size_t j = 0; j < _mReturn.cols(); j++)
1997 {
1998 _mReturn(i, j) /= dMax;
1999 }
2000 }
2001
2002 return _mReturn;
2003}
2004
2005
2019{
2020 size_t nLines = funcData.fVal.real();
2021 size_t nCols = funcData.nVal;
2022
2023 if (funcData.mat1.isEmpty() || !nLines || !nCols)
2025
2026 if (nLines * nCols != funcData.mat1.rows() * funcData.mat1.cols())
2028 toString(nLines) + "x" + toString(nCols) + "=" + toString(nLines*nCols) +" vs. "
2029 + printMatrixDim(funcData.mat1) + "=" + toString(funcData.mat1.rows()*funcData.mat1.cols()));
2030
2031 Matrix _mReturn = createFilledMatrix(nLines, nCols, 0.0);
2032
2033 for (size_t i = 0; i < nLines*nCols; i++)
2034 {
2035 _mReturn(i / nCols, i % nCols) = funcData.mat1(i / funcData.mat1.cols(), i % funcData.mat1.cols());
2036 }
2037
2038 return _mReturn;
2039}
2040
2041
2052{
2053 size_t n = funcData.fVal.real();
2054 size_t m = funcData.nVal;
2055
2056 if (n == 0)
2057 n++;
2058
2059 if (m == 0)
2060 m++;
2061
2062 if ((n * funcData.mat1.rows()) / funcData.mat1.rows() != n || (m * funcData.mat1.cols()) / funcData.mat1.cols() != m)
2064
2065 Matrix _mReturn = createFilledMatrix(n * funcData.mat1.rows(), m * funcData.mat1.cols(), 0.0);
2066
2067 #pragma omp parallel for
2068 for (size_t i = 0; i < funcData.mat1.rows(); i++)
2069 {
2070 for (size_t j = 0; j < funcData.mat1.cols(); j++)
2071 {
2072 for (size_t _n = 0; _n < n; _n++)
2073 {
2074 for (size_t _m = 0; _m < m; _m++)
2075 {
2076 _mReturn(i+_n*funcData.mat1.rows(), j+_m*funcData.mat1.cols()) = funcData.mat1(i, j);
2077 }
2078 }
2079 }
2080 }
2081
2082 return _mReturn;
2083}
2084
2085
2095static bool is_nan(const mu::value_type& value)
2096{
2097 return isnan(value);
2098}
2099
2100
2111static bool isSmallerRealOnly(const mu::value_type& value1, const mu::value_type& value2)
2112{
2113 return value1.real() < value2.real();
2114}
2115
2116
2126static std::vector<mu::value_type> getUniqueList(std::list<mu::value_type>& _list)
2127{
2128 _list.remove_if(is_nan);
2129
2130 if (_list.empty())
2131 return std::vector<mu::value_type>(1, NAN);
2132
2133 std::vector<mu::value_type> vReturn;
2134
2135 for (auto& val : _list)
2136 {
2137 if (std::find(vReturn.begin(), vReturn.end(), val) == vReturn.end())
2138 vReturn.push_back(val);
2139 }
2140
2141 std::sort(vReturn.begin(), vReturn.end(), isSmallerRealOnly);
2142
2143 return vReturn;
2144}
2145
2146
2157{
2158 if (funcData.mat1.isEmpty())
2160
2161 // Create a std::list and the return value
2162 std::list<mu::value_type> dataList;
2163 Matrix _mReturn;
2164
2165 // Depending on the dimensions of the passed matrix, change
2166 // the evaluation method
2167 if (funcData.mat1.rows() == 1)
2168 {
2169 // Row vector
2170 dataList.assign(funcData.mat1.data().begin(), funcData.mat1.data().end());
2171 auto uniqueList = getUniqueList(dataList);
2172 _mReturn.assign(1, uniqueList.size(), uniqueList);
2173 }
2174 else if (funcData.mat1.cols() == 1)
2175 {
2176 // Column vector
2177 dataList.assign(funcData.mat1.data().begin(), funcData.mat1.data().end());
2178 auto uniqueList = getUniqueList(dataList);
2179 _mReturn.assign(uniqueList.size(), 1, uniqueList);
2180 }
2181 else
2182 {
2183 // Matrix
2184 if (!funcData.nVal)
2185 {
2186 // funcData.nVal == 0 -> Roll out the total matrix and return it as a overall row vector
2187 Matrix retVal = matrixReshape(MatFuncData(funcData.mat1, mu::value_type(1.0), funcData.mat1.rows()*funcData.mat1.cols()),
2188 errorInfo);
2189 dataList.assign(retVal.data().begin(), retVal.data().end());
2190 auto uniqueList = getUniqueList(dataList);
2191 _mReturn.assign(uniqueList.size(), 1, uniqueList);
2192 }
2193 else if (funcData.nVal == 1)
2194 {
2195 std::vector<std::vector<mu::value_type>> mBuffer;
2196
2197 // Make the rows unique
2198 for (size_t i = 0; i < funcData.mat1.rows(); i++)
2199 {
2200 dataList.clear();
2201
2202 for (size_t j = 0; j < funcData.mat1.cols(); j++)
2203 dataList.push_back(funcData.mat1(i, j));
2204
2205 mBuffer.push_back(getUniqueList(dataList));
2206 }
2207
2208 _mReturn = Matrix(mBuffer);
2209 }
2210 else
2211 {
2212 std::vector<std::vector<mu::value_type>> mBuffer;
2213
2214 // Make the columns unique
2215 for (size_t j = 0; j < funcData.mat1.cols(); j++)
2216 {
2217 dataList.clear();
2218
2219 for (size_t i = 0; i < funcData.mat1.rows(); i++)
2220 dataList.push_back(funcData.mat1(i, j));
2221
2222 mBuffer.push_back(getUniqueList(dataList));
2223 }
2224
2225 _mReturn = Matrix(mBuffer);
2226 _mReturn.transpose();
2227 }
2228 }
2229
2230 return _mReturn;
2231}
2232
2233
2244{
2245 if (funcData.mat1.isEmpty())
2247
2248 // Create a std::list and the return value
2249 Matrix _mReturn;
2250
2251 // Depending on the dimensions of the passed matrix, change
2252 // the evaluation method
2253 if (funcData.mat1.rows() == 1 || funcData.mat1.cols() == 1)
2254 {
2255 _mReturn = funcData.mat1;
2256
2257 // (Any) vector
2258 std::vector<mu::value_type>& dat = _mReturn.data();
2259
2260 for (size_t i = 1; i < dat.size(); i++)
2261 {
2262 dat[i] += dat[i-1];
2263 }
2264 }
2265 else
2266 {
2267 // Matrix
2268 if (!funcData.nVal)
2269 {
2270 // funcData.nVal == 0 -> Roll out the total matrix and return it as a overall row vector
2271 _mReturn = matrixReshape(MatFuncData(funcData.mat1, mu::value_type(1.0), funcData.mat1.rows()*funcData.mat1.cols()),
2272 errorInfo);
2273 // (Any) vector
2274 std::vector<mu::value_type>& dat = _mReturn.data();
2275
2276 for (size_t i = 1; i < dat.size(); i++)
2277 {
2278 dat[i] += dat[i-1];
2279 }
2280 }
2281 else if (funcData.nVal == 1)
2282 {
2283 _mReturn = funcData.mat1;
2284
2285 // Calculate the cumsum along the rows
2286 for (size_t i = 0; i < _mReturn.rows(); i++)
2287 {
2288 for (size_t j = 1; j < _mReturn.cols(); j++)
2289 _mReturn(i, j) += _mReturn(i, j-1);
2290 }
2291 }
2292 else
2293 {
2294 _mReturn = funcData.mat1;
2295
2296 // Calculate the cumsum along the columns
2297 for (size_t j = 0; j < _mReturn.cols(); j++)
2298 {
2299 for (size_t i = 1; i < _mReturn.rows(); i++)
2300 _mReturn(i, j) += _mReturn(i-1, j);
2301 }
2302 }
2303 }
2304
2305 return _mReturn;
2306}
2307
2308
2319{
2320 if (funcData.mat1.isEmpty())
2322
2323 // Create a std::list and the return value
2324 Matrix _mReturn;
2325
2326 // Depending on the dimensions of the passed matrix, change
2327 // the evaluation method
2328 if (funcData.mat1.rows() == 1 || funcData.mat1.cols() == 1)
2329 {
2330 _mReturn = funcData.mat1;
2331
2332 // (Any) vector
2333 std::vector<mu::value_type>& dat = _mReturn.data();
2334
2335 for (size_t i = 1; i < dat.size(); i++)
2336 {
2337 dat[i] *= dat[i-1];
2338 }
2339 }
2340 else
2341 {
2342 // Matrix
2343 if (!funcData.nVal)
2344 {
2345 // funcData.nVal == 0 -> Roll out the total matrix and return it as a overall row vector
2346 _mReturn = matrixReshape(MatFuncData(funcData.mat1, mu::value_type(1.0), funcData.mat1.rows()*funcData.mat1.cols()),
2347 errorInfo);
2348 // (Any) vector
2349 std::vector<mu::value_type>& dat = _mReturn.data();
2350
2351 for (size_t i = 1; i < dat.size(); i++)
2352 {
2353 dat[i] *= dat[i-1];
2354 }
2355 }
2356 else if (funcData.nVal == 1)
2357 {
2358 _mReturn = funcData.mat1;
2359
2360 // Calculate the cumsum along the rows
2361 for (size_t i = 0; i < _mReturn.rows(); i++)
2362 {
2363 for (size_t j = 1; j < _mReturn.cols(); j++)
2364 _mReturn(i, j) *= _mReturn(i, j-1);
2365 }
2366 }
2367 else
2368 {
2369 _mReturn = funcData.mat1;
2370
2371 // Calculate the cumsum along the columns
2372 for (size_t j = 0; j < _mReturn.cols(); j++)
2373 {
2374 for (size_t i = 1; i < _mReturn.rows(); i++)
2375 _mReturn(i, j) *= _mReturn(i-1, j);
2376 }
2377 }
2378 }
2379
2380 return _mReturn;
2381}
2382
2383
2393static void solveLGSSymbolic(const Matrix& _mMatrix, const MatFuncErrorInfo& errorInfo)
2394{
2395 if (_mMatrix.isEmpty())
2397
2398 std::string sSolution = "sle(";
2399 std::vector<std::string> vResult(_mMatrix.cols()-1, "");
2400 bool bIsZeroesLine = true;
2401 unsigned int nVarCount = 0;
2402
2403 Matrix _mToSolve = createFilledMatrix(_mMatrix.cols()-1, _mMatrix.cols(), 0.0);
2404 Matrix _mCoefficents = createFilledMatrix(_mMatrix.cols()-1, _mMatrix.cols(), 0.0);
2405
2406 #pragma omp parallel for
2407 for (unsigned int i = 0; i < std::min(_mMatrix.rows(), _mMatrix.cols()-1); i++)
2408 {
2409 for (unsigned int j = 0; j < _mMatrix.cols(); j++)
2410 {
2411 _mToSolve(i, j) = _mMatrix(i, j);
2412 }
2413 }
2414
2415 for (int i = _mToSolve.rows()-1; i >= 0; i--)
2416 {
2417 bIsZeroesLine = true;
2418
2419 for (unsigned int j = 0; j < _mToSolve.cols(); j++)
2420 {
2421 if (bIsZeroesLine && _mToSolve(i, j) == 0.0)
2422 {
2423 bIsZeroesLine = false;
2424 break;
2425 }
2426 }
2427
2428 if (bIsZeroesLine)
2429 {
2430 _mCoefficents(i, i) = 1.0;
2431 nVarCount++;
2432 }
2433 else
2434 {
2435 // Konstanter Term
2436 _mCoefficents(i, _mCoefficents.cols()-1) = _mToSolve(i, _mToSolve.cols()-1);
2437
2438 for (unsigned int j = i+1; j < _mToSolve.cols()-1; j++)
2439 {
2440 if (_mToSolve(i, j) != 0.0)
2441 {
2442 // Konstanter Term
2443 _mCoefficents(i, _mCoefficents.cols()-1) -= _mToSolve(i, j) * _mCoefficents(j, _mCoefficents.cols()-1);
2444
2445 // Alle Koeffizienten
2446 for (unsigned int n = i+1; n < _mCoefficents.cols()-1; n++)
2447 {
2448 _mCoefficents(i, n) -= _mToSolve(i, j) * _mCoefficents(j, n);
2449 }
2450 }
2451 }
2452 }
2453 }
2454
2455 for (unsigned int i = 0; i < _mCoefficents.rows(); i++)
2456 {
2457 for (unsigned int j = 0; j < _mCoefficents.cols()-1; j++)
2458 {
2459 if (_mCoefficents(i, j) != 0.0)
2460 {
2461 if (fabs(_mCoefficents(i, j)) != 1.0)
2462 vResult[i] += toString(_mCoefficents(i, j), 5) + "*";
2463
2464 if (_mCoefficents(i, j) == -1.0)
2465 vResult[i] += "-";
2466
2467 vResult[i] += ('z'-vResult.size()+1+j);
2468 }
2469 }
2470
2471 if (_mCoefficents(i, _mCoefficents.cols()-1) != 0.0)
2472 vResult[i] += "+" + toString(_mCoefficents(i, _mCoefficents.cols()-1), 5);
2473
2474 while (vResult[i].find("+-") != std::string::npos)
2475 vResult[i].erase(vResult[i].find("+-"),1);
2476 }
2477
2478 for (unsigned int i = 0; i < nVarCount; i++)
2479 {
2480 sSolution += ('z'-nVarCount+i+1);
2481 }
2482
2483 sSolution += ") := {";
2484
2485 for (unsigned int i = 0; i < vResult.size(); i++)
2486 {
2487 sSolution += vResult[i];
2488
2489 if (i < vResult.size()-1)
2490 sSolution += ",";
2491 }
2492
2493 sSolution += "}";
2494
2495 NumeReKernel::print(sSolution);
2496 sSolution += " "+_lang.get("MATOP_SOLVELGSSYMBOLIC_DEFINECOMMENT");
2497
2498 bool bDefinitionSuccess = false;
2499
2501 const Settings& _option = NumeReKernel::getInstance()->getSettings();
2502
2503 if (!_functions.isDefined(sSolution))
2504 bDefinitionSuccess = _functions.defineFunc(sSolution);
2505 else if (_functions.getDefinitionString(_functions.getFunctionIndex(sSolution)) != sSolution)
2506 bDefinitionSuccess = _functions.defineFunc(sSolution, true);
2507 else if (_functions.getDefinitionString(_functions.getFunctionIndex(sSolution)) == sSolution)
2508 return;
2509
2510 if (bDefinitionSuccess)
2511 NumeReKernel::print(_lang.get("DEFINE_SUCCESS"), _option.systemPrints());
2512 else
2513 NumeReKernel::issueWarning(_lang.get("DEFINE_FAILURE"));
2514
2515 return;
2516}
2517
2518
2530{
2531 if (funcData.mat1.isEmpty())
2533
2534 Matrix _mResult = createFilledMatrix(funcData.mat1.cols()-1, 1, 0.0);
2535 Matrix _mToSolve = funcData.mat1;
2536
2537 if (_mToSolve.rows() == 1)
2538 {
2539 _mResult(0) = _mToSolve(0, 1)/_mToSolve(0);
2540 return _mResult;
2541 }
2542
2543 // Allgemeiner Fall fuer n > 2
2544 for (unsigned int j = 0; j < _mToSolve.cols()-1; j++)
2545 {
2546 for (unsigned int i = j; i < _mToSolve.rows(); i++)
2547 {
2548 if (_mToSolve(i, j) != 0.0)
2549 {
2550 if (i != j) //vertauschen
2551 {
2552 mu::value_type dElement;
2553
2554 for (unsigned int _j = 0; _j < _mToSolve.cols(); _j++)
2555 {
2556 dElement = _mToSolve(i, _j);
2557 _mToSolve(i, _j) = _mToSolve(j, _j);
2558 _mToSolve(j, _j) = dElement;
2559 }
2560
2561 i = j-1;
2562 }
2563 else //Gauss-Elimination
2564 {
2565 mu::value_type dPivot = _mToSolve(i, j);
2566
2567 for (unsigned int _j = 0; _j < _mToSolve.cols(); _j++)
2568 {
2569 _mToSolve(i, _j) /= dPivot;
2570 }
2571
2572 #pragma omp parallel for
2573 for (unsigned int _i = i+1; _i < _mToSolve.rows(); _i++)
2574 {
2575 mu::value_type dFactor = _mToSolve(_i, j);
2576
2577 if (dFactor == 0.0) // Bereits 0???
2578 continue;
2579
2580 for (unsigned int _j = 0; _j < _mToSolve.cols(); _j++)
2581 {
2582 _mToSolve(_i, _j) -= _mToSolve(i, _j)*dFactor;
2583 }
2584 }
2585
2586 break;
2587 }
2588 }
2589 /*else if (_mToSolve[i][j] == 0.0 && j+1 == _mToSolve.size()) // Matrix scheint keinen vollen Rang zu besitzen
2590 throw MATRIX_IS_NOT_INVERTIBLE;*/
2591 }
2592 }
2593
2594 if ((_mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-2) == 0.0 && _mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-1) == 0.0)
2595 || _mToSolve.rows()+1 < _mToSolve.cols())
2596 {
2597 NumeReKernel::print(toSystemCodePage(_lang.get("ERR_NR_2101_0_LGS_HAS_NO_UNIQUE_SOLUTION")));
2598 solveLGSSymbolic(_mToSolve, errorInfo);
2599 return _mToSolve;
2600 }
2601 else if (_mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-2) == 0.0 && _mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-1) != 0.0)
2603 else if ((_mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-2) == 0.0 && _mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-1) == 0.0)
2604 || _mToSolve.rows()+1 > _mToSolve.cols())
2605 {
2606 // Ggf. Nullzeilen nach unten tauschen
2607 std::vector<bool> vIsZerosLine(_mToSolve.rows(), true);
2608
2609 for (unsigned int i = 0; i < _mToSolve.rows(); i++)
2610 {
2611 for (unsigned int j = 0; j < _mToSolve.cols(); j++)
2612 {
2613 if (_mToSolve(i, j) != 0.0)
2614 {
2615 vIsZerosLine[i] = false;
2616 break;
2617 }
2618 }
2619 }
2620
2621 for (unsigned int i = 0; i < vIsZerosLine.size(); i++)
2622 {
2623 if (vIsZerosLine[i])
2624 {
2625 for (unsigned int _i = i+1; _i < vIsZerosLine.size(); _i++)
2626 {
2627 if (!vIsZerosLine[_i])
2628 {
2629 mu::value_type dElement;
2630
2631 for (unsigned int _j = 0; _j < _mToSolve.cols(); _j++)
2632 {
2633 dElement = _mToSolve(i, _j);
2634 _mToSolve(i, _j) = _mToSolve(_i, _j);
2635 _mToSolve(_i, _j) = dElement;
2636 }
2637
2638 vIsZerosLine[i] = false;
2639 vIsZerosLine[_i] = true;
2640 break;
2641 }
2642 }
2643 }
2644 }
2645
2646 if (_mToSolve(_mToSolve.cols()-2, _mToSolve.cols()-2) == 0.0 && _mToSolve(_mToSolve.cols()-2, _mToSolve.cols()-1) == 0.0)
2647 {
2648 NumeReKernel::print(toSystemCodePage(_lang.get("ERR_NR_2101_0_LGS_HAS_NO_UNIQUE_SOLUTION")));
2649 solveLGSSymbolic(_mToSolve, errorInfo);
2650 return _mToSolve;
2651 }
2652
2653 _mResult(_mResult.cols()-2, 0) = _mToSolve(_mToSolve.cols()-2, _mToSolve.cols()-1);
2654 }
2655 else
2656 _mResult(_mResult.rows()-1, 0) = _mToSolve(_mToSolve.rows()-1, _mToSolve.cols()-1);
2657
2658 for (int i = _mToSolve.cols()-3; i >= 0; i--)
2659 {
2660 for (unsigned int j = 0; j < _mToSolve.cols()-1; j++)
2661 {
2662 _mToSolve(i, _mToSolve.cols()-1) -= _mToSolve(i, j)*_mResult(j, 0);
2663
2664 if (_mToSolve(i, j)*_mResult(j, 0) != 0.0)
2665 _mToSolve(i, j) = 0.0;
2666 }
2667
2668 if (_mToSolve(i, i) == 0.0 && _mToSolve(i, _mToSolve.cols()-1) == 0.0)
2669 {
2670 NumeReKernel::print(toSystemCodePage(_lang.get("ERR_NR_2101_0_LGS_HAS_NO_UNIQUE_SOLUTION")));
2671 solveLGSSymbolic(_mToSolve, errorInfo);
2672 return _mToSolve;
2673 }
2674
2675 if (_mToSolve(i, i) == 0.0 && _mToSolve(i, _mToSolve.cols()-1) != 0.0)
2677
2678 _mResult(i, 0) = _mToSolve(i, _mToSolve.cols()-1);
2679 }
2680
2681 return _mResult;
2682}
2683
2684
2695{
2696 if (funcData.mat1.isEmpty())
2698
2699 Matrix _reshapedMat = matrixReshape(MatFuncData(funcData.mat1, mu::value_type(funcData.mat1.rows() * funcData.mat1.cols()), 1),
2700 errorInfo);
2701 Matrix _diagonalMat = createFilledMatrix(_reshapedMat.rows(), _reshapedMat.rows(), 0.0);
2702
2703 for (size_t i = 0; i < _reshapedMat.rows(); i++)
2704 {
2705 _diagonalMat(i, i) = _reshapedMat(i);
2706 }
2707
2708 return _diagonalMat;
2709}
2710
2711
2722{
2723 if (funcData.mat1.isEmpty())
2725
2726 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2728 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2729
2730 Matrix _mReturn = funcData.mat1;
2731
2732 #pragma omp parallel for
2733 for (size_t i = 0; i < _mReturn.rows(); i++)
2734 {
2735 _mReturn(i, 0) = std::sqrt(intPower(funcData.mat1(i, 0), 2) + intPower(funcData.mat1(i, 1), 2));
2736 _mReturn(i, 1) = parser_phi(funcData.mat1(i, 0), funcData.mat1(i, 1));
2737 }
2738
2739 return _mReturn;
2740}
2741
2742
2753{
2754 if (funcData.mat1.isEmpty())
2756
2757 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2759 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2760
2761 if (funcData.mat1.cols() == 2)
2762 return cartToCyl(funcData, errorInfo);
2763
2764 Matrix _mReturn = funcData.mat1;
2765
2766 #pragma omp parallel for
2767 for (size_t i = 0; i < _mReturn.rows(); i++)
2768 {
2769 _mReturn(i, 0) = std::sqrt(intPower(funcData.mat1(i, 0), 2)
2770 + intPower(funcData.mat1(i, 1), 2)
2771 + intPower(funcData.mat1(i, 2), 2));
2772 _mReturn(i, 1) = parser_phi(funcData.mat1(i, 0), funcData.mat1(i, 1));
2773 _mReturn(i, 2) = parser_theta(funcData.mat1(i, 0), funcData.mat1(i, 1), funcData.mat1(i, 2));
2774 }
2775
2776 return _mReturn;
2777}
2778
2779
2790{
2791 if (funcData.mat1.isEmpty())
2793
2794 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2796 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2797
2798 Matrix _mReturn = funcData.mat1;
2799
2800 #pragma omp parallel for
2801 for (size_t i = 0; i < _mReturn.rows(); i++)
2802 {
2803 _mReturn(i, 0) = funcData.mat1(i, 0) * cos(funcData.mat1(i, 1));
2804 _mReturn(i, 1) = funcData.mat1(i, 0) * sin(funcData.mat1(i, 1));
2805 }
2806
2807 return _mReturn;
2808}
2809
2810
2821{
2822 if (funcData.mat1.isEmpty())
2824
2825 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2827 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2828
2829 if (funcData.mat1.cols() == 2)
2830 return funcData.mat1;
2831
2832 Matrix _mReturn = funcData.mat1;
2833
2834 #pragma omp parallel for
2835 for (size_t i = 0; i < _mReturn.rows(); i++)
2836 {
2837 _mReturn(i, 0) = std::sqrt(intPower(funcData.mat1(i, 0), 2) + intPower(funcData.mat1(i, 2), 2));
2838 _mReturn(i, 2) = parser_theta(funcData.mat1(i, 0) * cos(funcData.mat1(i, 1)),
2839 funcData.mat1(i, 0) * sin(funcData.mat1(i, 1)),
2840 funcData.mat1(i, 2));
2841 }
2842
2843 return _mReturn;
2844}
2845
2846
2857{
2858 if (funcData.mat1.isEmpty())
2860
2861 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2863 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2864
2865 if (funcData.mat1.cols() == 2)
2866 return cylToCart(funcData, errorInfo);
2867
2868 Matrix _mReturn = funcData.mat1;
2869
2870 #pragma omp parallel for
2871 for (size_t i = 0; i < _mReturn.rows(); i++)
2872 {
2873 _mReturn(i, 0) = funcData.mat1(i, 0) * cos(funcData.mat1(i, 1)) * sin(funcData.mat1(i, 2));
2874 _mReturn(i, 1) = funcData.mat1(i, 0) * sin(funcData.mat1(i, 1)) * sin(funcData.mat1(i, 2));
2875 _mReturn(i, 2) = funcData.mat1(i, 0) * cos(funcData.mat1(i, 2));
2876 }
2877
2878 return _mReturn;
2879}
2880
2881
2892{
2893 if (funcData.mat1.isEmpty())
2895
2896 if (funcData.mat1.cols() > 3 || funcData.mat1.cols() < 2)
2898 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x3");
2899
2900 Matrix _mReturn = funcData.mat1;
2901
2902 #pragma omp parallel for
2903 for (size_t i = 0; i < _mReturn.rows(); i++)
2904 {
2905 _mReturn(i, 0) = funcData.mat1(i, 0) * sin(funcData.mat1(i, 2));
2906
2907 if (funcData.mat1.cols() == 3)
2908 _mReturn(i, 2) = funcData.mat1(i, 0) * cos(funcData.mat1(i, 2));
2909 }
2910
2911 return _mReturn;
2912}
2913
2914
2925static size_t findNearestLowerGridAxisValue(const Matrix& gaxes, size_t axis, double axisval)
2926{
2927 int sign = gaxes(0, axis).real() > gaxes(gaxes.cols()-1, axis).real() ? -1 : 1;
2928
2929 for (size_t i = 0; i < gaxes.rows(); i++)
2930 {
2931 if (sign * gaxes(i, axis).real() >= sign * axisval)
2932 {
2933 if (i)
2934 return i-1;
2935
2936 return 0u;
2937 }
2938 }
2939
2940 return gaxes.rows()-1;
2941}
2942
2943
2955{
2956 if (funcData.mat1.rows() < 2 || !funcData.mat1.cols() || funcData.mat2.isEmpty())
2958
2959 if (funcData.mat1.cols() > 2)
2961 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat1.rows()) + "x2");
2962
2963 if (funcData.mat2.cols() > 2)
2965 printMatrixDim(funcData.mat2) + " vs. "+ toString(funcData.mat2.rows()) + "x2");
2966
2967 if (funcData.mat2.cols() == 2 && funcData.mat1.cols() < 2)
2969 printMatrixDim(funcData.mat1) + " vs. "+ toString(funcData.mat2.rows()) + "x2");
2970
2971 Matrix gcoords = funcData.mat2;
2972
2973 #pragma omp parallel for
2974 for (size_t i = 0; i < gcoords.rows(); i++)
2975 {
2976 for (size_t j = 0; j < gcoords.cols(); j++)
2977 {
2978 size_t pos = findNearestLowerGridAxisValue(funcData.mat1, j, gcoords(i, j).real()); // find the lower grid axis value assuming sorted axis
2979 mu::value_type off = gcoords(i, j) - funcData.mat1(pos, j); // should be smaller than grid interval, but might be negative
2980 mu::value_type interval = pos+1 < funcData.mat1.rows()
2981 ? funcData.mat1(pos+1, j) - funcData.mat1(pos, j)
2982 : funcData.mat1(pos, j) - funcData.mat1(pos-1, j); // the grid interval. Might also be negative
2983
2984 gcoords(i, j) = pos + 1 + off.real() / interval.real(); // if off == interval, then pos+1, else pos + (<1) and +1 due to zero-based coords
2985 }
2986 }
2987
2988 return gcoords;
2989}
2990
2991
3002static mu::value_type readMat(const Matrix& mat, int row, int col)
3003{
3004 if (row < (int)mat.rows() && col < (int)mat.cols() && row >= 0 && col >= 0)
3005 return mat(row, col);
3006 else
3007 return NAN;
3008}
3009
3010
3021static mu::value_type bilinearInterpolation(const Matrix& mat, double row, double col)
3022{
3023 if (std::isnan(row) || std::isnan(col))
3024 return NAN;
3025
3026 // Find the base index
3027 int nBaseLine = intCast(row) + (row < 0 ? -1 : 0);
3028 int nBaseCol = intCast(col) + (col < 0 ? -1 : 0);
3029
3030 // Get the decimal part of the double indices
3031 double x = row - nBaseLine;
3032 double y = col - nBaseCol;
3033
3034 // Find the surrounding four entries
3035 mu::value_type f00 = readMat(mat, nBaseLine, nBaseCol);
3036 mu::value_type f10 = readMat(mat, nBaseLine+1, nBaseCol);
3037 mu::value_type f01 = readMat(mat, nBaseLine, nBaseCol+1);
3038 mu::value_type f11 = readMat(mat, nBaseLine+1, nBaseCol+1);
3039
3040 // If all are NAN, return NAN
3041 if (isnan(f00) && isnan(f01) && isnan(f10) && isnan(f11))
3042 return NAN;
3043
3044 // Otherwise set NAN to zero
3045 f00 = isnan(f00) ? 0.0 : f00;
3046 f10 = isnan(f10) ? 0.0 : f10;
3047 f01 = isnan(f01) ? 0.0 : f01;
3048 f11 = isnan(f11) ? 0.0 : f11;
3049
3050 // f(0,0) (1-x) (1-y) + f(1,0) x (1-y) + f(0,1) (1-x) y + f(1,1) x y
3051 return f00*(1-x)*(1-y) + f10*x*(1-y) + f01*(1-x)*y + f11*x*y;
3052}
3053
3054
3067{
3068 if (funcData.mat1.isEmpty() || funcData.mat2.isEmpty())
3070
3071 if (funcData.mat2.cols() >= 2 && funcData.mat1.cols() <= 2)
3073 printMatrixDim(funcData.mat1) + " vs. " + printMatrixDim(funcData.mat2));
3074
3075 Matrix interp = createFilledMatrix(funcData.mat2.rows(), std::max(1u, funcData.mat2.cols()-1), 0.0);
3076
3077 // Interpolate all values in the matrix mat2. First
3078 // column contains the row values, all remaining contain
3079 // the corresponding col values
3080 #pragma omp parallel for
3081 for (size_t i = 0; i < funcData.mat2.rows(); i++)
3082 {
3083 if (funcData.mat2.cols() >= 2)
3084 {
3085 for (size_t j = 1; j < funcData.mat2.cols(); j++)
3086 {
3087 interp(i, j-1) = bilinearInterpolation(funcData.mat1, funcData.mat2(i, 0).real()-1.0, funcData.mat2(i, j).real()-1.0);
3088 }
3089 }
3090 else
3091 interp(i, 0) = bilinearInterpolation(funcData.mat1, funcData.mat2(i, 0).real()-1.0, 0.0);
3092 }
3093
3094 return interp;
3095}
3096
3097
3109static Matrix hcat(const MatFuncData& funcData, const MatFuncErrorInfo& errorInfo)
3110{
3111 // Check the dimensions of the two matrices
3112 if (funcData.mat1.rows() != funcData.mat2.rows())
3114 printMatrixDim(funcData.mat1) + " vs. " + printMatrixDim(funcData.mat2));
3115
3116 return funcData.mat1.hcat(funcData.mat2);
3117}
3118
3119
3131static Matrix vcat(const MatFuncData& funcData, const MatFuncErrorInfo& errorInfo)
3132{
3133 // Check the dimensions of the two matrices
3134 if (funcData.mat1.cols() != funcData.mat2.cols())
3136 printMatrixDim(funcData.mat1) + " vs. " + printMatrixDim(funcData.mat2));
3137
3138 return funcData.mat1.vcat(funcData.mat2);
3139}
3140
3141
3152{
3153 if (funcData.mat1.isEmpty()
3154 || funcData.mat2.isEmpty()
3155 || funcData.mat3.isEmpty())
3157 printMatrixDim(funcData.mat1) + " vs. " + printMatrixDim(funcData.mat2));
3158
3159 // Store the scalar state
3160 bool isScalar[2] = {funcData.mat2.isScalar(),
3161 funcData.mat3.isScalar()};
3162
3163 if (!isScalar[0]
3164 && !isScalar[1]
3165 && (funcData.mat2.rows() != funcData.mat3.rows() || funcData.mat2.cols() != funcData.mat3.cols()))
3167 printMatrixDim(funcData.mat2) + " vs. " + printMatrixDim(funcData.mat3));
3168
3169 // Prepare the return value
3170 Matrix selected = createFilledMatrix(std::max(funcData.mat2.rows(), funcData.mat3.rows()),
3171 std::max(funcData.mat2.cols(), funcData.mat3.cols()), NAN);
3172
3173 int row = 0;
3174 int col = 0;
3175
3176 // Store the scalar values
3177 if (isScalar[0])
3178 row = intCast(funcData.mat2(0))-1;
3179
3180 if (isScalar[1])
3181 col = intCast(funcData.mat3(0))-1;
3182
3183 #pragma omp parallel for firstprivate(row,col)
3184 for (size_t i = 0; i < selected.rows(); i++)
3185 {
3186 for (size_t j = 0; j < selected.cols(); j++)
3187 {
3188 // Get the values, if they are no scalars
3189 if (!isScalar[0])
3190 row = intCast(funcData.mat2(i, j))-1;
3191
3192 if (!isScalar[1])
3193 col = intCast(funcData.mat3(i, j))-1;
3194
3195 // Extract the selected value
3196 if (row >= 0 && row < (int)funcData.mat1.rows()
3197 && col >= 0 && col < (int)funcData.mat1.cols())
3198 selected(i, j) = funcData.mat1(row, col);
3199 }
3200 }
3201
3202 return selected;
3203}
3204
3205
3217{
3218 if (funcData.mat1.isEmpty()
3219 || funcData.mat2.isEmpty()
3220 || funcData.mat3.isEmpty())
3222
3223 // Store the scalar state
3224 bool isScalar[2] = {funcData.mat1.isScalar(),
3225 funcData.mat2.isScalar()};
3226
3227 if (!isScalar[0]
3228 && !isScalar[1]
3229 && (funcData.mat1.rows() != funcData.mat2.rows()
3230 || funcData.mat1.cols() != funcData.mat2.cols()
3231 || funcData.mat1.rows() != funcData.mat3.rows()
3232 || funcData.mat1.cols() != funcData.mat3.cols()))
3234 printMatrixDim(funcData.mat1) + " vs. " + printMatrixDim(funcData.mat2) + " vs. " + printMatrixDim(funcData.mat3));
3235
3236 // Prepare the return value
3237 int rows = calculateStats(funcData.mat1, StatsLogic(StatsLogic::OPERATION_MAX, funcData.mat1(0).real()),
3238 0, funcData.mat1.rows(), 0, funcData.mat1.cols()).real();
3239
3240 int cols = calculateStats(funcData.mat2, StatsLogic(StatsLogic::OPERATION_MAX, funcData.mat2(0).real()),
3241 0, funcData.mat2.rows(), 0, funcData.mat2.cols()).real();
3242
3243 // Prepare the filled matrix
3244 Matrix assembled = createFilledMatrix(rows, cols, NAN);
3245
3246 int row = 0;
3247 int col = 0;
3248
3249 // Store the scalar values
3250 if (isScalar[0])
3251 row = intCast(funcData.mat1(0))-1;
3252
3253 if (isScalar[1])
3254 col = intCast(funcData.mat2(0))-1;
3255
3256 #pragma omp parallel for firstprivate(row,col)
3257 for (size_t i = 0; i < funcData.mat3.rows(); i++)
3258 {
3259 for (size_t j = 0; j < funcData.mat3.cols(); j++)
3260 {
3261 // Get the values, if they are no scalars
3262 if (!isScalar[0])
3263 row = intCast(funcData.mat1(i, j))-1;
3264
3265 if (!isScalar[1])
3266 col = intCast(funcData.mat2(i, j))-1;
3267
3268 assembled(row, col) = funcData.mat3(i, j);
3269 }
3270 }
3271
3272 return assembled;
3273}
3274
3275
3288{
3289 if (funcData.mat1.isEmpty())
3291
3292 if (funcData.mat1.cols() < 2)
3294 printMatrixDim(funcData.mat1));
3295
3296 Matrix mRes = createZeroesMatrix(1, 1);
3297
3298 for (size_t i = 0; i < funcData.mat1.rows()-1; i++)
3299 {
3300 double sum = 0;
3301
3302 for (size_t j = 0; j < funcData.mat1.cols(); j++)
3303 {
3304 sum += ((funcData.mat1(i+1, j) - funcData.mat1(i, j)) * conj(funcData.mat1(i+1, j) - funcData.mat1(i, j))).real();
3305 }
3306
3307 mRes(0) += sqrt(sum);
3308 }
3309
3310 return mRes;
3311}
3312
3313
3326static mu::value_type applyKernel(const Matrix& kernel, const Matrix& inMatrix, const VectorIndex& rows, const VectorIndex& cols, const size_t startRow, const size_t startCol)
3327{
3328 // Init the result to zero
3329 mu::value_type result(0);
3330
3331 // Perform element wise multiplication and sum up each result
3332 for (size_t i = 0; i < kernel.rows(); i++)
3333 {
3334 for (size_t j = 0; j < kernel.cols(); j++)
3335 {
3336 result += kernel(i, j) * inMatrix(rows[startRow + i], cols[startCol + j]);
3337 }
3338 }
3339
3340 return result;
3341}
3342
3343
3355{
3356 // mat1 -> matrix to filter, mat2 -> filter kernel, nVal -> boundary mode
3357
3358 // Check that matrix and the filter are not empty
3359 if (funcData.mat1.isEmpty() || funcData.mat2.isEmpty())
3361
3362 // Check if mode is valid
3363 if (funcData.nVal < 0 || funcData.nVal > 1)
3364 {
3365 std::string sMode = std::to_string(funcData.nVal);
3367 }
3368
3369 // Check if filter size is valid for the given matrix, check that filter has an uneven number of rows and cols
3370 if (funcData.mat2.rows() > funcData.mat1.rows() || funcData.mat2.cols() > funcData.mat1.cols() || !(funcData.mat2.rows() % 2) || !(funcData.mat2.cols() % 2))
3372
3373 // Define the offset that is half the filter size
3374 size_t offsetRows = (funcData.mat2.rows() - 1) / 2;
3375 size_t offsetCols = (funcData.mat2.cols() - 1) / 2;
3376
3377 // Generate the vectors with indices that represent the matrix rows and cols
3378 VectorIndex rows(0, funcData.mat1.rows() - 1);
3379 VectorIndex cols(0, funcData.mat1.cols() - 1);
3380
3381 // Add additional indices that represent the boundary condition
3382 switch (funcData.nVal)
3383 {
3384 case 0: // boundary clamp
3385 rows.prepend(std::vector<int>(offsetRows, 0));
3386 rows.append(std::vector<int>(offsetRows, funcData.mat2.rows() - 1));
3387 cols.prepend(std::vector<int>(offsetCols, 0));
3388 cols.append(std::vector<int>(offsetCols, funcData.mat2.cols() - 1));
3389 break;
3390 case 1: // boundary reflect
3391 rows.prepend(VectorIndex(offsetRows, 1));
3392 rows.append(VectorIndex(funcData.mat2.rows() - 1, funcData.mat2.rows() - offsetRows));
3393 cols.prepend(VectorIndex(offsetCols, 1));
3394 cols.append(VectorIndex(funcData.mat2.rows() - 1, funcData.mat2.rows() - offsetRows));
3395 break;
3396 }
3397
3398 // Generate the result matrix
3399 Matrix _mResult = createFilledMatrix(funcData.mat1.rows(), funcData.mat1.cols(), NAN);
3400
3401 // Calculate the results
3402 #pragma omp parallel for
3403 for (int i = 0; i < (int)_mResult.rows(); i++)
3404 {
3405 for (int j = 0; j < (int)_mResult.cols(); j++)
3406 {
3407 // Multiply the two matrices using a helper function
3408 _mResult(i, j) = applyKernel(funcData.mat2, funcData.mat1, rows, cols, i, j);
3409 }
3410 }
3411
3412 return _mResult;
3413}
3414
3415
3426{
3428}
3429
3430
3438static std::map<std::string,MatFuncDef> getMatrixFunctions()
3439{
3440 std::map<std::string,MatFuncDef> mFunctions;
3441
3442 mFunctions["cross"] = MatFuncDef(MATSIG_MAT, calcCrossProduct);
3443 mFunctions["det"] = MatFuncDef(MATSIG_MAT, getDeterminant);
3444 mFunctions["trace"] = MatFuncDef(MATSIG_MAT, calcTrace);
3445 mFunctions["eigenvals"] = MatFuncDef(MATSIG_MAT, calcEigenValues);
3446 mFunctions["eigenvects"] = MatFuncDef(MATSIG_MAT, calcEigenVects);
3447 mFunctions["diagonalize"] = MatFuncDef(MATSIG_MAT, diagonalize);
3448 mFunctions["invert"] = MatFuncDef(MATSIG_MAT, invertMatrix);
3449 mFunctions["transpose"] = MatFuncDef(MATSIG_MAT, transposeMatrix);
3450 mFunctions["logtoidx"] = MatFuncDef(MATSIG_MAT, logToIndex);
3451 mFunctions["idxtolog"] = MatFuncDef(MATSIG_MAT, indexToLog);
3452 mFunctions["size"] = MatFuncDef(MATSIG_MAT, matrixSize);
3453 mFunctions["and"] = MatFuncDef(MATSIG_MAT, matrixAnd, false);
3454 mFunctions["or"] = MatFuncDef(MATSIG_MAT, matrixOr, false);
3455 mFunctions["xor"] = MatFuncDef(MATSIG_MAT, matrixXor, false);
3456 mFunctions["sum"] = MatFuncDef(MATSIG_MAT, matrixSum, false);
3457 mFunctions["std"] = MatFuncDef(MATSIG_MAT, matrixStd, false);
3458 mFunctions["avg"] = MatFuncDef(MATSIG_MAT, matrixAvg, false);
3459 mFunctions["prd"] = MatFuncDef(MATSIG_MAT, matrixPrd, false);
3460 mFunctions["cnt"] = MatFuncDef(MATSIG_MAT, matrixCnt, false);
3461 mFunctions["cutoff"] = MatFuncDef(MATSIG_MAT_F_N, matrixCutoff);
3462 mFunctions["num"] = MatFuncDef(MATSIG_MAT, matrixNum, false);
3463 mFunctions["norm"] = MatFuncDef(MATSIG_MAT, matrixNorm, false);
3464 mFunctions["min"] = MatFuncDef(MATSIG_MAT, matrixMin, false);
3465 mFunctions["max"] = MatFuncDef(MATSIG_MAT, matrixMax, false);
3466 mFunctions["minpos"] = MatFuncDef(MATSIG_MAT, matrixMinPos, false);
3467 mFunctions["maxpos"] = MatFuncDef(MATSIG_MAT, matrixMaxPos, false);
3468 mFunctions["med"] = MatFuncDef(MATSIG_MAT, matrixMed, false);
3469 mFunctions["pct"] = MatFuncDef(MATSIG_MAT_F, matrixPct, false);
3470 mFunctions["cmp"] = MatFuncDef(MATSIG_MAT_F_N, matrixCmp, false);
3471 mFunctions["movsum"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovSum);
3472 mFunctions["movstd"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovStd);
3473 mFunctions["movavg"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovAvg);
3474 mFunctions["movprd"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovPrd);
3475 mFunctions["movmed"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovMed);
3476 mFunctions["movmin"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovMin);
3477 mFunctions["movmax"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovMax);
3478 mFunctions["movnorm"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovNorm);
3479 mFunctions["movnum"] = MatFuncDef(MATSIG_MAT_N_MOPT, matrixMovNum);
3480 mFunctions["zero"] = MatFuncDef(MATSIG_N_MOPT, createZeroesMatrix);
3481 mFunctions["one"] = MatFuncDef(MATSIG_N_MOPT, createOnesMatrix);
3482 mFunctions["identity"] = MatFuncDef(MATSIG_N_MOPT, identityMatrix);
3483 mFunctions["shuffle"] = MatFuncDef(MATSIG_N_MOPT, createShuffledMatrix);
3484 mFunctions["correl"] = MatFuncDef(MATSIG_MAT_MAT, correlation);
3485 mFunctions["covar"] = MatFuncDef(MATSIG_MAT_MAT, covariance);
3486 mFunctions["normalize"] = MatFuncDef(MATSIG_MAT, normalize);
3487 mFunctions["reshape"] = MatFuncDef(MATSIG_MAT_F_N, matrixReshape);
3488 mFunctions["resize"] = MatFuncDef(MATSIG_MAT_F_N, matrixResize);
3489 mFunctions["repmat"] = MatFuncDef(MATSIG_MAT_F_N, matrixRepMat);
3490 mFunctions["unique"] = MatFuncDef(MATSIG_MAT_NOPT, matrixUnique);
3491 mFunctions["cumsum"] = MatFuncDef(MATSIG_MAT_NOPT, matrixCumSum);
3492 mFunctions["cumprd"] = MatFuncDef(MATSIG_MAT_NOPT, matrixCumPrd);
3493 mFunctions["solve"] = MatFuncDef(MATSIG_MAT, solveLGS);
3494 mFunctions["diag"] = MatFuncDef(MATSIG_MAT, diagonalMatrix);
3495 mFunctions["carttocyl"] = MatFuncDef(MATSIG_MAT, cartToCyl);
3496 mFunctions["carttopol"] = MatFuncDef(MATSIG_MAT, cartToPolar);
3497 mFunctions["cyltocart"] = MatFuncDef(MATSIG_MAT, cylToCart);
3498 mFunctions["cyltopol"] = MatFuncDef(MATSIG_MAT, cylToPolar);
3499 mFunctions["poltocart"] = MatFuncDef(MATSIG_MAT, polarToCart);
3500 mFunctions["poltocyl"] = MatFuncDef(MATSIG_MAT, polarToCyl);
3501 mFunctions["coordstogrid"] = MatFuncDef(MATSIG_MAT_MAT, coordsToGrid);
3502 mFunctions["interpolate"] = MatFuncDef(MATSIG_MAT_MAT, interpolate);
3503 mFunctions["hcat"] = MatFuncDef(MATSIG_MAT_MAT, hcat);
3504 mFunctions["vcat"] = MatFuncDef(MATSIG_MAT_MAT, vcat);
3505 mFunctions["select"] = MatFuncDef(MATSIG_MAT_MAT_MAT, selection);
3506 mFunctions["assemble"] = MatFuncDef(MATSIG_MAT_MAT_MAT, assemble);
3507 mFunctions["polylength"] = MatFuncDef(MATSIG_MAT, polyLength);
3508 mFunctions["filter"] = MatFuncDef(MATSIG_MAT_MAT_N, matrixFilter);
3509
3510 // For finding matrix functions
3511 mFunctions["matfl"] = MatFuncDef(MATSIG_INVALID, invalidMatrixFunction);
3512 mFunctions["matflf"] = MatFuncDef(MATSIG_INVALID, invalidMatrixFunction);
3513 mFunctions["matfc"] = MatFuncDef(MATSIG_INVALID, invalidMatrixFunction);
3514 mFunctions["matfcf"] = MatFuncDef(MATSIG_INVALID, invalidMatrixFunction);
3515
3516 return mFunctions;
3517}
3518
3519#endif // MATFUNCS_HPP
3520
This class implements the function definition managing instance.
Definition: define.hpp:74
std::string getDefinitionString(size_t _i) const
Returns the definition string of the ith defined custom function.
Definition: define.cpp:964
bool defineFunc(const std::string &sExpr, bool bRedefine=false, bool bFallback=false)
This function defines a custom function, by passing it to a new FunctionDefinition class instance.
Definition: define.cpp:655
bool isDefined(const std::string &sFunc)
This method checks, whether the passed function is already defined.
Definition: define.cpp:625
size_t getFunctionIndex(const std::string &sFuncName)
Returns the numerical index of the selected custom defined functions.
Definition: define.hpp:179
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
This class defines a dynamic size 2D matrix with a single 1D internal buffer. If the internal buffer ...
std::string printDims() const
Convert the dimensions to a printable string.
Matrix vcat(const Matrix &mat) const
Vertically concatenate two matrices.
std::vector< mu::value_type > & data()
Get a reference to the internal data structure.
void resize(size_t r, size_t c)
Resize the matrix to another dimension. New elements will be zero-initialized.
bool isSquare() const
Simple function to identify square matrices.
bool isEmpty() const
Simple function to identify empty matrices.
size_t cols() const
The cols of this matrix.
void assign(const Matrix &mat)
Assign a matrix.
size_t rows() const
The rows of this matrix.
void transpose()
Transpose this matrix.
bool isScalar() const
Check, whether this matrix is actually a scalar.
Matrix hcat(const Matrix &mat) const
Horizontally concatenate two matrices.
bool containsInvalidValues() const
Returns true, if this matrix contains invalid values.
This class represents a single table in memory, or a - so to say - single memory page to be handled b...
Definition: memory.hpp:68
void writeData(int _nLine, int _nCol, const mu::value_type &_dData)
This member function writes the passed value to the selected position. The table is automatically enl...
Definition: memory.cpp:1219
mu::value_type pct(const VectorIndex &_vLine, const VectorIndex &_vCol, mu::value_type dPct=0.5) const
Implementation for the PCT multi argument function.
Definition: memory.cpp:2803
void writeDataDirectUnsafe(int _nLine, int _nCol, const mu::value_type &_dData)
This member function provides an even more unsafe but direct way of writing data to the table....
Definition: memory.cpp:1271
mu::value_type med(const VectorIndex &_vLine, const VectorIndex &_vCol) const
Implementation for the MED multi argument function.
Definition: memory.cpp:2736
static NumeReKernel * getInstance()
This static member function returns a a pointer to the singleton instance of the kernel.
Definition: kernel.hpp:221
static void print(const std::string &__sLine, bool printingEnabled=true)
This member function appends the passed string as a new output line to the buffer and informs the ter...
Definition: kernel.cpp:2636
FunctionDefinitionManager & getDefinitions()
Definition: kernel.hpp:291
static void issueWarning(std::string sWarningMessage)
This static function may be used to issue a warning to the user. The warning will be printed by the t...
Definition: kernel.cpp:2833
Settings & getSettings()
Definition: kernel.hpp:296
This class manages the setting values of the internal (kernel) settings of this application.
Definition: settings.hpp:663
bool systemPrints() const
Returns, whether system messages shall be printed to the terminal.
Definition: settings.hpp:1140
Common exception class for all exceptions thrown in NumeRe.
Definition: error.hpp:32
@ MATRIX_IS_NOT_INVERTIBLE
Definition: error.hpp:153
@ INVALID_STATS_WINDOW_SIZE
Definition: error.hpp:144
@ CUTOFF_MODE_INVALID
Definition: error.hpp:92
@ INVALID_MODE
Definition: error.hpp:147
@ MATRIX_CONTAINS_INVALID_VALUES
Definition: error.hpp:156
@ MATRIX_CANNOT_HAVE_ZERO_SIZE
Definition: error.hpp:155
@ FUNCTION_ERROR
Definition: error.hpp:110
@ WRONG_MATRIX_DIMENSIONS_FOR_MATOP
Definition: error.hpp:227
@ LGS_HAS_NO_SOLUTION
INSERT HERE.
Definition: error.hpp:150
@ TOO_LARGE_CACHE
Definition: error.hpp:217
@ INVALID_FILTER_SIZE
Definition: error.hpp:148
This class abstracts all the index logics, i.e. the logical differences between single indices and in...
Definition: structures.hpp:42
void prepend(const std::vector< int > &vVector)
This function will prepend the passed vector before the beginning of the index vector....
Definition: structures.hpp:491
void append(const std::vector< int > &vVector)
This function will append the passed vector to the end of the index vector. The internal storage is e...
Definition: structures.hpp:451
Language _lang
Definition: kernel.cpp:39
std::string toSystemCodePage(std::string)
Converts an internal to an external string. Does nothing currently.
value_type parser_theta(const value_type &x, const value_type &y, const value_type &z)
This function calculates the angle of a vector and the z axis in any z-r plane (the polar angle theta...
value_type parser_phi(const value_type &x, const value_type &y)
This function calculates the angle of a vector and the x axis in the x-y plane (the azimuthal angle p...
@ MATSIG_MAT_F
@ MATSIG_MAT
@ MATSIG_MAT_F_N
@ MATSIG_N_MOPT
@ MATSIG_MAT_MAT_MAT
@ MATSIG_MAT_MAT
@ MATSIG_MAT_MAT_N
@ MATSIG_MAT_N_MOPT
@ MATSIG_MAT_NOPT
@ MATSIG_INVALID
static Matrix coordsToGrid(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function converts floating point coordinates to grid coordinates by using the grid axes a...
Definition: matfuncs.hpp:2954
static Matrix polyLength(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Calculates the length of an open polygon. If the circumference of a closed polygon shall be calculate...
Definition: matfuncs.hpp:3287
static mu::value_type calculateStats(const Matrix &mat, StatsLogic logic, int rowStart, size_t rowCount, int colStart, size_t colCount)
Driver code to calculate some statistics from a matrix while being able to use moving windows....
Definition: matfuncs.hpp:778
static Matrix cylToCart(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts cylindrical to cartesian coordinates.
Definition: matfuncs.hpp:2789
static Matrix matrixMovNorm(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the norm() function.
Definition: matfuncs.hpp:1529
static Matrix calcEigenVects(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Calculates the eigenvectors of the passed matrix.
Definition: matfuncs.hpp:442
static Matrix logToIndex(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function converts logical vectors into matrix indices.
Definition: matfuncs.hpp:703
static Matrix polarToCart(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts polar to cartesian coordinates.
Definition: matfuncs.hpp:2856
static Matrix vcat(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static functions concatenates two matrices vertically. This is, the number of columns stays the ...
Definition: matfuncs.hpp:3131
static Matrix matrixCmp(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the cmp() function on the matrix elements.
Definition: matfuncs.hpp:1618
static Matrix matrixMovNum(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the num() function.
Definition: matfuncs.hpp:1169
static Matrix cartToPolar(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts cartesian to polar coordinates.
Definition: matfuncs.hpp:2752
static Matrix solveLGS(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function will solve the system of linear equations passed as matrix using the Gauss elimi...
Definition: matfuncs.hpp:2529
static Matrix matrixMovMax(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the max() function.
Definition: matfuncs.hpp:858
#define EIGENVALUES
Definition: matfuncs.hpp:22
static mu::value_type applyKernel(const Matrix &kernel, const Matrix &inMatrix, const VectorIndex &rows, const VectorIndex &cols, const size_t startRow, const size_t startCol)
This static helper function applies the kernel to the subset of a matrix using the provided indices.
Definition: matfuncs.hpp:3326
static Matrix polarToCyl(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts polar to cylindrical coordinates.
Definition: matfuncs.hpp:2891
static std::vector< mu::value_type > getUniqueList(std::list< mu::value_type > &_list)
This is a static helper function for the implementation of the unique() function.
Definition: matfuncs.hpp:2126
static Matrix diagonalize(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Diagonalizes the passed matrix using its eigenvalues.
Definition: matfuncs.hpp:472
#define DIAGONALIZE
Definition: matfuncs.hpp:24
static Matrix matrixMin(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the min() function on the matrix elements.
Definition: matfuncs.hpp:1564
static Matrix matrixMovMin(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the min() function.
Definition: matfuncs.hpp:1583
static std::string printMatrixDim(const Matrix &mat)
Simple helper for printing the matrix dimensions to a string.
Definition: matfuncs.hpp:47
Matrix _mEigenVects
Definition: matfuncs.hpp:370
static Matrix interpolate(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function wraps the bilinear interpolation algorithm for interpolating the values of the f...
Definition: matfuncs.hpp:3066
static Matrix matrixAnd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the and() function on the matrix elements.
Definition: matfuncs.hpp:1005
static Matrix matrixOr(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the or() function on the matrix elements.
Definition: matfuncs.hpp:1032
static Matrix indexToLog(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function converts matrix indices into logical vectors.
Definition: matfuncs.hpp:893
static Matrix selection(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Extracts a selection from a matrix iterating through two matrices simultaneously.
Definition: matfuncs.hpp:3151
static Matrix cylToPolar(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts cylindrical to polar coordinates.
Definition: matfuncs.hpp:2820
static Matrix matrixCutoff(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies a threshold to the complete matrix as specified by the arguments.
Definition: matfuncs.hpp:1411
static bool is_nan(const mu::value_type &value)
Static helper function for std::list::remove_if() called in getUniqueList().
Definition: matfuncs.hpp:2095
static Matrix matrixAvg(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the avg() function on the matrix elements.
Definition: matfuncs.hpp:1204
static Matrix createShuffledMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function creates a shuffled vector of nShuffle elements created from a 1:nBase vector.
Definition: matfuncs.hpp:488
static size_t findNearestLowerGridAxisValue(const Matrix &gaxes, size_t axis, double axisval)
This static function finds the nearest lower grid axis value.
Definition: matfuncs.hpp:2925
static Matrix diagonalMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the "diag()" function.
Definition: matfuncs.hpp:2694
static Matrix matrixMovSum(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the sum() function.
Definition: matfuncs.hpp:1115
static Matrix matrixSize(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function returns the size of the passed matrix.
Definition: matfuncs.hpp:979
static Matrix getDeterminant(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function calculates the determinant of the passed matrix.
Definition: matfuncs.hpp:256
static Matrix matrixPrd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the prd() function on the matrix elements.
Definition: matfuncs.hpp:1338
Eigen::ComplexEigenSolver< Eigen::MatrixXcd > eSolver(mMatrix)
static Matrix createOnesMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function returns a matrix filled with ones of the defined size.
Definition: matfuncs.hpp:103
static Matrix matrixXor(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the xor() function on the matrix elements.
Definition: matfuncs.hpp:1059
static Matrix matrixStd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the std() function on the matrix elements.
Definition: matfuncs.hpp:1268
static Matrix hcat(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static functions concatenates two matrices horizontally. This is, the number of rows stays the s...
Definition: matfuncs.hpp:3109
static Matrix matrixMaxPos(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the maxpos() function on the matrix elements.
Definition: matfuncs.hpp:1716
static std::map< std::string, MatFuncDef > getMatrixFunctions()
Returns a map containing all declared and "standard" matrix functions.
Definition: matfuncs.hpp:3438
static Matrix matrixMax(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the max() function on the matrix elements.
Definition: matfuncs.hpp:839
Eigen::MatrixXcd mMatrix(_mMatrix.rows(), _mMatrix.rows())
static Matrix transposeMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function transposes a matrix.
Definition: matfuncs.hpp:686
static Matrix matrixMinPos(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the minpos() function on the matrix elements.
Definition: matfuncs.hpp:1698
static Matrix matrixSum(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the sum() function on the matrix elements.
Definition: matfuncs.hpp:1096
static Matrix identityMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function returns an identity matrix of the defined size.
Definition: matfuncs.hpp:127
int nReturnType
Definition: matfuncs.hpp:357
static Matrix createZeroesMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function returns a matrix filled with zeros of the defined size.
Definition: matfuncs.hpp:79
__attribute__((force_align_arg_pointer)) static Matrix calcEigenVectsAndValues(const Matrix &_mMatrix
This static function does the whole eigenvalues, eigenvectors and diagonalizing stuff.
static Matrix calcCrossProduct(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function calulates the n-dimensional cross product ("curl").
Definition: matfuncs.hpp:279
#define EIGENVECTORS
Definition: matfuncs.hpp:23
static Matrix calcTrace(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function calculates the trace of the passed matrix.
Definition: matfuncs.hpp:152
if(!_mMatrix.isSquare()) throw SyntaxError(SyntaxError if(_mMatrix.containsInvalidValues()) throw SyntaxError(SyntaxError Matrix _mEigenVals
Definition: matfuncs.hpp:366
static Matrix matrixUnique(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the unique(MAT,nDim) function.
Definition: matfuncs.hpp:2156
static Matrix covariance(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the covariance calculation of the passed two matrices.
Definition: matfuncs.hpp:1935
static Matrix matrixCumSum(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the cumsum(MAT,nDim) function.
Definition: matfuncs.hpp:2243
static mu::value_type bilinearInterpolation(const Matrix &mat, double row, double col)
Performs the bilinear interpolation of the matrix value at the selected coordinates.
Definition: matfuncs.hpp:3021
static Matrix matrixFilter(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Function that allows the user to apply a customer filter kernel to a matrix while applying different ...
Definition: matfuncs.hpp:3354
static Matrix matrixMed(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the med() function on the matrix elements.
Definition: matfuncs.hpp:1734
static Matrix cartToCyl(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Converts cartesian to cylindrical coordinates.
Definition: matfuncs.hpp:2721
static mu::value_type readMat(const Matrix &mat, int row, int col)
Static helper function for bilinearInterpolation().
Definition: matfuncs.hpp:3002
static Matrix calcEigenValues(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Calculates the eigenvalues of the passed matrix.
Definition: matfuncs.hpp:457
static Matrix matrixMovAvg(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the avg() function.
Definition: matfuncs.hpp:1225
static Matrix matrixCumPrd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the cumprd(MAT,nDim) function.
Definition: matfuncs.hpp:2318
static Matrix matrixPct(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the pct() function on the matrix elements.
Definition: matfuncs.hpp:1816
static Matrix assemble(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Assembles a matrix from coordinates and values (a datagrid replacement without interpolation).
Definition: matfuncs.hpp:3216
static Matrix matrixMovPrd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the prd() function.
Definition: matfuncs.hpp:1357
static Matrix normalize(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the normalize function, which will normalize the (absolute) data rang...
Definition: matfuncs.hpp:1982
static Matrix matrixRepMat(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function repeats the passed matrix n and m times.
Definition: matfuncs.hpp:2051
std::mt19937 & getRandGenInstance()
Returns a reference to the central random number generator instance, which is globally accessible by ...
Definition: tools.cpp:91
static bool isSmallerRealOnly(const mu::value_type &value1, const mu::value_type &value2)
Static helper function for std::sort() called in getUniqueList(). Determines a real-only order.
Definition: matfuncs.hpp:2111
static Matrix matrixMovMed(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the med() function.
Definition: matfuncs.hpp:1764
static void solveLGSSymbolic(const Matrix &_mMatrix, const MatFuncErrorInfo &errorInfo)
This static function solves the system of linear equations symbolically.
Definition: matfuncs.hpp:2393
static mu::value_type calcDeterminant(const Matrix &_mMatrix, std::vector< int > vRemovedLines)
This static function calculates the determinant of the passed matrix using the LaPlace algorithm.
Definition: matfuncs.hpp:182
static Matrix matrixReshape(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function changes the number of rows and columns to fit the new shape.
Definition: matfuncs.hpp:2018
static Matrix invalidMatrixFunction(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Static invalid matrix function, which will always throw an error.
Definition: matfuncs.hpp:3425
static Matrix matrixNum(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the num() function on the matrix elements.
Definition: matfuncs.hpp:1150
static Matrix matrixCnt(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the cnt() function on the matrix elements.
Definition: matfuncs.hpp:1392
static Matrix matrixMovStd(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Moving window version of the std() function.
Definition: matfuncs.hpp:1292
int const MatFuncErrorInfo & errorInfo
Definition: matfuncs.hpp:358
static Matrix createFilledMatrix(size_t n, size_t m, const mu::value_type &val)
This static function returns a matrix filled with the passed value of the defined size.
Definition: matfuncs.hpp:64
static Matrix invertMatrix(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
Calculates the inverse matrix and checks in advance, whether the matrix is invertible.
Definition: matfuncs.hpp:536
static Matrix matrixNorm(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function applies the norm() function on the matrix elements.
Definition: matfuncs.hpp:1507
static Matrix correlation(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function implements the cross- and auto-correlation matrix calculation from the passed tw...
Definition: matfuncs.hpp:1877
static Matrix matrixResize(const MatFuncData &funcData, const MatFuncErrorInfo &errorInfo)
This static function changes the size of the passed matrix to fit the new size.
Definition: matfuncs.hpp:1847
std::complex< double > intPower(const std::complex< double > &, int)
This function calculates the power of a value with the specialization that the exponent is an integer...
Definition: tools.cpp:3640
CONSTCD11 std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1317
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:251
bool isnan(const value_type &v)
Definition: muParserDef.h:379
std::vector< double > real(const std::vector< value_type > &vVec)
bool isinf(const value_type &v)
Definition: muParserDef.h:374
value_type rint(value_type v)
#define min(a, b)
Definition: resampler.cpp:34
#define max(a, b)
Definition: resampler.cpp:30
Defines a Matrix.
mu::value_type fVal
const Matrix & mat3
const Matrix & mat1
const Matrix & mat2
Defines a matrix function itself by containing the signature, the pointer to the implementation and a...
Defines the needed information for displaying a reasonable error information.
const std::string & command
Simplify the creation of some statistics by externalizing the operation code and unifying the driver ...
Definition: statslogic.hpp:30
@ OPERATION_ADDSQSUB
Definition: statslogic.hpp:36
long long int intCast(const std::complex< double > &)
Casts the real part of the complex number to an integer and avoids rounding errors.
Definition: tools.cpp:1824
std::string toString(int)
Converts an integer to a string without the Settings bloat.