// Copyright (C) 2003-2009 Marc Duruflé
// Copyright (C) 2001-2009 Vivien Mallet
//
// This file is part of the linear-algebra library Seldon,
// http://seldon.sourceforge.net/.
//
// Seldon is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your option)
// any later version.
//
// Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
// more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Seldon. If not, see http://www.gnu.org/licenses/.
#ifndef SELDON_FILE_FUNCTIONS_MATRIX_ARRAY_CXX
/*
Functions defined in this file:
(storage ArrayRowSparse, ArrayColSparse, etc)
alpha.M*X + beta.Y -> Y
MltAdd(alpha, M, X, beta, Y)
alpha.A + B -> B
Add(alpha, A, B)
alpha.M -> M
Mlt(alpha, M)
*/
namespace Seldon
{
////////////
// MltAdd //
/*** ArrayRowSymComplexSparse ***/
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha, const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(), n, p;
T1 val;
T3 val_cplx;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val = A.ValueReal(i, k);
if (p == i)
C(i) += val * B(i);
else
{
C(i) += val * B(p);
C(p) += val * B(i);
}
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val = A.ValueImag(i, k);
if (p == i)
C(i) += complex<T1>(0, val) * B(i);
else
{
C(i) += complex<T1>(0, val) * B(p);
C(p) += complex<T1>(0, val) * B(i);
}
}
}
}
else // alpha != 1.
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val_cplx = alpha * A.ValueReal(i, k);
if (p == i)
C(i) += val_cplx * B(i);
else
{
C(i) += val_cplx * B(p);
C(p) += val_cplx * B(i);
}
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
if (p == i)
C(i) += val_cplx * B(i);
else
{
C(i) += val_cplx * B(p);
C(p) += val_cplx * B(i);
}
}
}
}
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonNoTrans& Trans, const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonTrans& Trans, const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonConjTrans& Trans, const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(),n,p;
T1 val;
T3 val_cplx;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val = A.ValueReal(i, k);
if (p == i)
C(i) += val * B(i);
else
{
C(i) += val * B(p);
C(p) += val * B(i);
}
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val = A.ValueImag(i, k);
if (p == i)
C(i) -= complex<T1>(0, val) * B(i);
else
{
C(i) -= complex<T1>(0, val) * B(p);
C(p) -= complex<T1>(0, val) * B(i);
}
}
}
}
else
{
// alpha different from 1
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val_cplx = alpha * A.ValueReal(i, k);
if (p == i)
C(i) += val_cplx * B(i);
else
{
C(i) += val_cplx * B(p);
C(p) += val_cplx * B(i);
}
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
if (p == i)
C(i) -= val_cplx * B(i);
else
{
C(i) -= val_cplx * B(p);
C(p) -= val_cplx * B(i);
}
}
}
}
}
/*** ArrayRowComplexSparse ***/
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(), n, p;
T1 val;
T3 val_cplx;
if (alpha == T0(1, 0))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val = A.ValueReal(i, k);
C(i) += val * B(p);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val = A.ValueImag(i, k);
C(i) += complex<T1>(0, val) * B(p);
}
}
}
else
{
// alpha different from 1
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val_cplx = alpha * A.ValueReal(i, k);
C(i) += val_cplx * B(p);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
C(i) += val_cplx * B(p);
}
}
}
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonNoTrans& Trans, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonTrans& Trans, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(),n,p;
T1 val;
T3 val_cplx;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val = A.ValueReal(i, k);
C(p) += val * B(i);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val = A.ValueImag(i, k);
C(p) += complex<T1>(0, val) * B(i);
}
}
}
else
{
// alpha different from 1
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val_cplx = alpha * A.ValueReal(i, k);
C(p) += val_cplx * B(i);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
C(p) += val_cplx * B(i);
}
}
}
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonConjTrans& Trans, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(),n,p;
T1 val;
T3 val_cplx;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val = A.ValueReal(i, k);
C(p) += val * B(i);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val = A.ValueImag(i, k);
C(p) -= complex<T1>(0, val) * B(i);
}
}
}
else
{
// alpha different from 1
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexReal(i, k);
val_cplx = alpha * A.ValueReal(i, k);
C(p) += val_cplx * B(i);
}
n = A.GetImagRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.IndexImag(i, k);
val_cplx -= alpha * complex<T1>(0, A.ValueImag(i, k));
C(p) += val_cplx * B(i);
}
}
}
}
/*** ArrayRowSymSparse ***/
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha, const Matrix<T1, Symmetric,
ArrayRowSymSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (B.GetM() <= 0)
return;
T3 zero(B(0));
zero *= 0;
if (beta == zero)
C.Fill(zero);
else
Mlt(beta, C);
int m = A.GetM(), n, p;
T1 val;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = A.Value(i, k);
if (p == i)
C(i) += val * B(i);
else
{
C(i) += val * B(p);
C(p) += val * B(i);
}
}
}
}
else
{
// alpha different from 1
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = alpha * A.Value(i, k);
if (p==i)
C(i) += val * B(i);
else
{
C(i) += val * B(p);
C(p) += val * B(i);
}
}
}
}
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonNoTrans& Trans, const Matrix<T1, Symmetric,
ArrayRowSymSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonTrans& Trans, const Matrix<T1, Symmetric,
ArrayRowSymSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
/*** ArrayRowSparse ***/
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(), n, p;
T1 val;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = A.Value(i, k);
C(i) += val * B(p);
}
}
}
else // alpha != 1.
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = A.Value(i, k);
C(i) += alpha * val * B(p);
}
}
}
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonNoTrans& Trans,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T4, VectFull, Allocator3>& C)
{
MltAdd(alpha, A, B, beta, C);
}
template<class T0, class T1, class T2, class T3, class T4,
class Allocator1, class Allocator2, class Allocator3>
void MltAdd(const T0& alpha,
const class_SeldonTrans& Trans,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Vector<T2, VectFull, Allocator2>& B,
const T4& beta,
Vector<T3, VectFull, Allocator3>& C)
{
if (beta == T4(0))
C.Fill(T3(0));
else
Mlt(beta, C);
int m = A.GetM(), n, p;
T1 val;
if (alpha == T0(1))
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = A.Value(i, k);
C(p) += val * B(i);
}
}
}
else // alpha != 1.
{
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
for (int k = 0; k < n ; k++)
{
p = A.Index(i, k);
val = A.Value(i, k);
C(p) += alpha * val * B(i);
}
}
}
}
// MltAdd //
////////////
/////////
// Add //
template<class T0, class T1, class T2, class Allocator1, class Allocator2>
void Add(const T0& alpha,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
Matrix<T2, General, ArrayRowSparse, Allocator2>& B)
{
int m = B.GetM(),n;
Vector<T2, VectFull, Allocator2> value;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = T2(A.Value(i, j));
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetIndex(i), value.GetData());
}
}
template<class T0, class T1, class T2, class Allocator1, class Allocator2>
void Add(const T0& alpha,
const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B)
{
int m = B.GetM(),n;
Vector<T2, VectFull, Allocator2> value;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = A.Value(i, j);
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetIndex(i), value.GetData());
}
}
template<class T0, class T1, class T2, class Allocator1, class Allocator2>
void Add(const T0& alpha,
const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
Matrix<T2, Symmetric, ArrayRowSymComplexSparse, Allocator2>& B)
{
int m = B.GetM(), n, ni;
Vector<complex<T2> > value;
IVect index;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
ni = A.GetImagRowSize(i);
value.Reallocate(n + ni);
index.Reallocate(n + ni);
for (int j = 0; j < n; j++)
{
value(j) = A.ValueReal(i, j);
index(j) = A.IndexReal(i, j);
}
for (int j = 0; j < ni; j++)
{
value(j+n) = complex<T2>(0, 1) * A.ValueImag(i, j);
index(j+n) = A.IndexImag(i, j);
}
Mlt(alpha, value);
B.AddInteractionRow(i, n+ni, index, value);
}
}
template<class T0, class T1, class T2, class Allocator1, class Allocator2>
void Add(const T0& alpha, const Matrix<T1, Symmetric,
ArrayRowSymComplexSparse, Allocator1>& A,
Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B)
{
int m = B.GetM(), n;
Vector<T2, VectFull, Allocator2> value;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = A.ValueReal(i, j);
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetRealInd(i), value.GetData());
n = A.GetImagRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = complex<T1>(0, 1) * A.ValueImag(i, j);
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetImagInd(i), value.GetData());
}
}
template<class T0, class T1, class T2, class Allocator1, class Allocator2>
void Add(const T0& alpha, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
Matrix<T2, Symmetric, ArrayRowSparse, Allocator2>& B)
{
int m = B.GetM(),n;
Vector<T2, VectFull, Allocator2> value;
for (int i = 0; i < m; i++)
{
n = A.GetRealRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = A.ValueReal(i, j);
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetRealInd(i), value.GetData());
n = A.GetImagRowSize(i);
value.Reallocate(n);
for (int j = 0; j < n; j++)
value(j) = complex<T1>(0, 1) * A.ValueImag(i, j);
Mlt(alpha, value);
B.AddInteractionRow(i, n, A.GetImagInd(i), value.GetData());
}
}
template<class T0, class T1, class T2, class Allocator1,class Allocator2>
void Add(const T0& alpha, const Matrix<T1, General,
ArrayRowComplexSparse, Allocator1>& A,
Matrix<T2, General, ArrayRowComplexSparse, Allocator2>& B)
{
int m = B.GetM(), n, ni;
Vector<complex<T2> > value; IVect index;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRealRowSize(i);
ni = A.GetImagRowSize(i);
value.Reallocate(n + ni);
index.Reallocate(n + ni);
for (int j = 0; j < n; j++)
{
value(j) = A.ValueReal(i, j);
index(j) = A.IndexReal(i, j);
}
for (int j = 0; j < n; j++)
{
value(n+j) = complex<T2>(0, 1) * A.ValueImag(i, j);
index(n+j) = A.IndexImag(i, j);
}
Mlt(alpha, value);
B.AddInteractionRow(i, n+ni, index, value);
}
}
// C = C + complex(A,B)
template<class T0, class T1, class T2, class T3, class Allocator1,
class Allocator2, class Allocator3>
void Add(const T0& alpha,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Matrix<T2, General, ArrayRowSparse, Allocator2>& B,
Matrix<complex<T3>, General, ArrayRowSparse, Allocator3>& C)
{
int m = B.GetM(),n1,n2,size_row;;
Vector<complex<T3>, VectFull, Allocator3> val_row;
IVect ind_row;
for (int i = 0 ; i < m ; i++)
{
n1 = A.GetRowSize(i);
n2 = B.GetRowSize(i);
size_row = n1 + n2;
val_row.Reallocate(size_row);
ind_row.Reallocate(size_row);
for (int j = 0 ; j < n1 ; j++)
{
ind_row(j) = A.Index(i, j);
val_row(j) = alpha*complex<T3>(A.Value(i, j), 0);
}
for (int j = 0 ; j < n2 ; j++)
{
ind_row(j+n1) = B.Index(i, j);
val_row(j+n1) = alpha * complex<T3>(B.Value(i, j));
}
C.AddInteractionRow(i, size_row, ind_row, val_row);
}
}
// C = C + complex(A,B)
template<class T0, class T1, class T2, class T3,
class Allocator1, class Allocator2, class Allocator3>
void Add(const T0& alpha,
const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
const Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B,
Matrix<complex<T3>, Symmetric, ArrayRowSymSparse, Allocator3>& C)
{
int m = B.GetM(), n1, n2, size_row;
Vector<complex<T3>, VectFull, Allocator3> val_row;
IVect ind_row;
for (int i = 0 ; i < m ; i++)
{
n1 = A.GetRowSize(i);
n2 = B.GetRowSize(i);
size_row = n1 + n2;
val_row.Reallocate(size_row);
ind_row.Reallocate(size_row);
for (int j = 0 ; j < n1 ; j++)
{
ind_row(j) = A.Index(i, j);
val_row(j) = alpha * complex<T3>(A.Value(i, j), 0);
}
for (int j = 0 ; j < n2 ; j++)
{
ind_row(j+n1) = B.Index(i, j);
val_row(j+n1) = alpha * complex<T3>(B.Value(i, j));
}
C.AddInteractionRow(i, size_row, ind_row, val_row);
}
}
// C = C + complex(A,B)
template<class T0, class T1, class T2, class T3,
class Allocator1, class Allocator2, class Allocator3>
void Add(const T0& alpha,
const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
const Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B,
Matrix<T3, Symmetric, ArrayRowSymComplexSparse, Allocator3>& C)
{
int m = B.GetM(), n, ni;
Vector<complex<T3> > value; IVect index;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
ni = B.GetRowSize(i);
value.Reallocate(n+ni);
index.Reallocate(n+ni);
for (int j = 0; j < n; j++)
{
value(j) = A.Value(i, j);
index(j) = A.Index(i, j);
}
for (int j = 0; j < ni; j++)
{
value(n+j) = complex<T3>(0, 1) * B.Value(i, j);
index(n+j) = B.Index(i, j);
}
Mlt(alpha, value);
C.AddInteractionRow(i, n+ni, index, value);
}
}
// C = C + complex(A,B)
template<class T0, class T1, class T2, class T3,
class Allocator1, class Allocator2, class Allocator3>
void Add(const T0& alpha,
const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Matrix<T2, General, ArrayRowSparse, Allocator2>& B,
Matrix<T3, General, ArrayRowComplexSparse, Allocator3>& C)
{
int m = B.GetM(), n, ni;
Vector<complex<T3> > value;
IVect index;
for (int i = 0 ; i < m ; i++)
{
n = A.GetRowSize(i);
ni = B.GetRowSize(i);
value.Reallocate(n + ni);
index.Reallocate(n + ni);
for (int j = 0; j < n; j++)
{
value(j) = A.Value(i, j);
index(j) = A.Index(i, j);
}
for (int j = 0; j < ni; j++)
{
value(n+j) = complex<T3>(0, 1) * B.Value(i, j);
index(n+j) = B.Index(i, j);
}
Mlt(alpha, value);
C.AddInteractionRow(i, n+ni, index, value);
}
}
// Add //
/////////
/////////
// Mlt //
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha, Matrix<T, General, ArrayRowSparse, Allocator>& A)
{
for (int i = 0; i < A.GetM(); i++)
for (int j = 0; j < A.GetRowSize(i); j++)
A.Value(i,j) *= alpha;
}
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha, Matrix<T, General, ArrayColSparse, Allocator>& A)
{
for (int i = 0; i < A.GetN(); i++)
for (int j = 0; j < A.GetColSize(i); j++)
A.Value(i,j) *= alpha;
}
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha,
Matrix<T, Symmetric, ArrayRowSymSparse, Allocator>& A)
{
for (int i = 0; i < A.GetM(); i++)
for (int j = 0; j < A.GetRowSize(i); j++)
A.Value(i,j) *= alpha;
}
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha,
Matrix<T, Symmetric, ArrayColSymSparse, Allocator>& A)
{
for (int i = 0; i < A.GetN(); i++)
for (int j = 0; j < A.GetColSize(i); j++)
A.Value(i,j) *= alpha;
}
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha,
Matrix<T, General, ArrayRowComplexSparse, Allocator>& A)
{
for (int i = 0; i < A.GetM(); i++)
{
for (int j = 0; j < A.GetRealRowSize(i); j++)
A.ValueReal(i,j) *= alpha;
for (int j = 0; j < A.GetImagRowSize(i); j++)
A.ValueImag(i,j) *= alpha;
}
}
template<class T0, class T, class Allocator>
void Mlt(const T0& alpha, Matrix<T, Symmetric,
ArrayRowSymComplexSparse, Allocator>& A)
{
for (int i = 0; i < A.GetM(); i++)
{
for (int j = 0; j < A.GetRealRowSize(i); j++)
A.ValueReal(i,j) *= alpha;
for (int j = 0; j < A.GetImagRowSize(i); j++)
A.ValueImag(i,j) *= alpha;
}
}
// Matrix-matrix product (sparse matrix against full matrix)
template<class T1, class Allocator1, class T2, class Prop2,
class Storage2, class Allocator2, class T3, class Prop3,
class Storage3, class Allocator3>
void Mlt(const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
const Matrix<T2, Prop2, Storage2, Allocator2>& B,
Matrix<T3, Prop3, Storage3, Allocator3>& C)
{
int m = A.GetM();
int n = B.GetN();
C.Reallocate(m,n);
T3 val;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
val = T3(0);
for (int ind = 0; ind < A.GetRowSize(i); ind++)
{
int k = A.Index(i, ind);
val += A.Value(i, ind) * B(k, j);
}
C(i, j) = val;
}
}
// Mlt //
/////////
} // namespace Seldon
#define SELDON_FILE_FUNCTIONS_MATRIX_ARRAY_CXX
#endif