Content |
Complex Vectors and Matrices
When you are working with complex vectors and matrices dealing with real and imaginary parts is a common task. The following is supported in FLENS:
-
For complex valued dense vectors you can create real valued dense vectors that reference the real or imaginary vector parts. This is possible as as a dense vector reference can reference elements that are separated by a constant stride.
-
For complex valued matrices of type GeMatrix we support copying the real and imaginary parts to a real valued matrix and vice versa. Note that it is not possible that a GeMatrix view can be used to reference the real or imaginary part of a complex valued GeMatrix:
-
If a GeMatrix stores elements in row major order then row elements must be contiguously in memory. However, complete rows can be separated by a constant stride.
-
If a GeMatrix stores elements in col major order then column elements must be contiguously in memory. However, complete columns can be separated by a constant stride.
If you have complex elements and want to reference only the real or imaginary part there always will be gaps. So a new matrix type is defined for this case. However, BLAS functionality for this type is limited to copy.
-
Complex Vectors
#include <iostream>
#include <flens/flens.cxx>
using namespace flens;
using namespace std;
int
main()
{
typedef complex<double> Complex;
DenseVector<Array<Complex> > z(5);
z = Complex(1,2), Complex(3,4), Complex(5,6), Complex(7,8), Complex(9,10);
Underscore<int> _;
auto x = real(z);
auto y = imag(z);
cout << "z = " << z << endl;
cout << "real(z) = " << x << endl;
cout << "imag(z) = " << y << endl;
x = 2, 9, 4, 7, 6;
y(_(1,2,5)) = 666, -666, 666;
cout << "z = " << z << endl;
blas::swap(x,y);
cout << "z = " << z << endl;
}
So some notes about what is going on :import: flens/examples/complex-densevector-views.cc [brief]
So let's compile and run the example:
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. complex-densevector-views.cc $shell> ./a.out z = (1,2) (3,4) (5,6) (7,8) (9,10) real(z) = 1 3 5 7 9 imag(z) = 2 4 6 8 10 z = (2,666) (9,4) (4,-666) (7,8) (6,666) z = (666,2) (4,9) (-666,4) (8,7) (666,6)
Complex Matrices
#include <iostream>
#include <flens/flens.cxx>
using namespace flens;
using namespace std;
int
main()
{
typedef GeMatrix<FullStorage<complex<double> > > ComplexGeMatrix;
typedef GeMatrix<FullStorage<double> > RealGeMatrix;
const int m = 5;
const int n = 4;
ComplexGeMatrix Z(m,n);
ComplexGeMatrix::IndexVariable i,j;
Z(i,j) = Complex(i+j,j-i);
RealGeMatrix X = real(Z);
RealGeMatrix Y;
Y = imag(Z);
cout << "Z = " << Z << endl;
cout << "real(Z) = " << X << endl;
cout << "imag(Z) = " << Y << endl;
real(Z) = Y;
imag(Z) = X;
cout << "Z = " << Z << endl;
}
So some notes about what is going on :import: flens/examples/complex-gematrix-views.cc [brief]
So let's compile and run the example:
$shell> cd flens/examples $shell> g++ -Wall -std=c++11 -I../.. complex-gematrix-views.cc $shell> ./a.out Z = (2,0) (3,1) (4,2) (5,3) (3,-1) (4,0) (5,1) (6,2) (4,-2) (5,-1) (6,0) (7,1) (5,-3) (6,-2) (7,-1) (8,0) (6,-4) (7,-3) (8,-2) (9,-1) real(Z) = 2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8 6 7 8 9 imag(Z) = 0 1 2 3 -1 0 1 2 -2 -1 0 1 -3 -2 -1 0 -4 -3 -2 -1 Z = (0,2) (1,3) (2,4) (3,5) (-1,3) (0,4) (1,5) (2,6) (-2,4) (-1,5) (0,6) (1,7) (-3,5) (-2,6) (-1,7) (0,8) (-4,6) (-3,7) (-2,8) (-1,9)