package ppmrmn;
/**
* An n x n square complex matrix class with
* n = 4 for a spin I = 3/2,
* n = 6 for a spin I = 5/2,
* n = 8 for a spin I = 7/2,
* n = 10 for a spin I = 9/2.
* re is the double value matrix for the real part,
* im is the double value matrix for the imaginary part.
*/
public class ComplexMat {
protected static int n;
protected double[][] re = new double[n][n];
protected double[][] im = new double[n][n];
//--------------//
// Constructors //
//--------------//
/**
* Constructor of an n x n square complex matrix.
* @param preal the double value matrix for the real part
* of the square complex matrix
* @param pimag the double value matrix for the imaginary part
* of the square complex matrix
*/
public ComplexMat(double[][] preal, double[][] pimag) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
re[i][j] = preal[i][j];
im[i][j] = pimag[i][j];
}
}
/**
* Constructor of an n x n square complex matrix with zeroed imaginary part.
* @param preal the double value matrix for the real part
* of the square complex matrix
*/
public ComplexMat(double[][] preal) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
re[i][j] = preal[i][j];
im[i][j] = 0;
}
}
/**
* Constructor of an n x n square complex matrix with zeroed elements.
*/
public ComplexMat() {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
re[i][j] = 0;
im[i][j] = 0;
}
}
//---------//
// Setters //
//---------//
/**
* Set the dimension of the square complex matrix with
* i = 4 for a spin I = 3/2,
* i = 6 for a spin I = 5/2,
* i = 8 for a spin I = 7/2,
* i = 10 for a spin I = 9/2.
*/
public static void setMatrixSize (int i) {
n = i;
}
//---------//
// Getters //
//---------//
/**
* Get the dimension n of the n x n square complex matrix.
* @return the dimension n of the square complex matrix
*/
public static int getN() {
return n;
}
//-------------------//
// Matrix operations //
//-------------------//
/**
* Multiply two n x n square complex matrices.
* @param a the left-hand side square complex matrix
* @param b the right-hand side square complex matrix
* @return the product matrix (a square complex matrix)
*/
public ComplexMat matMultiply(ComplexMat a, ComplexMat b) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++) {
c.re[i][j] += a.re[i][k]*b.re[k][j] - a.im[i][k]*b.im[k][j];
c.im[i][j] += a.re[i][k]*b.im[k][j] + a.im[i][k]*b.re[k][j];
}
return c;
}
/**
* Complex conjugate of an n x n square complex matrix.
* @param a the original square complex matrix
* @return the complex conjugated matrix
*/
public ComplexMat matConjugue(ComplexMat a) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = a.re[i][j];
c.im[i][j] = -a.im[i][j];
}
return c;
}
/**
* Copy an n x n square complex matrix.
* @param a the original square complex matrix
* @return the copied square complex matrix
*/
public ComplexMat matCopy(ComplexMat a) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = a.re[i][j];
c.im[i][j] = a.im[i][j];
}
return c;
}
/**
* Print the elements of an n x n square complex matrix.
* @param a the original square complex matrix
*/
public void matPrint(ComplexMat a) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print("" + a.re[i][j] + " xx " + a.im[i][j] + " ** ");
}
System.out.println();
System.out.println();
}
}
/**
* Return a string representation of the system.
* @return java.lang.String
* Use System.out.println(matc.re);
* to print the real part of the square complex matrix matc
*/
public String toString(double[][] c) {
StringBuffer sb = new StringBuffer();
char[] separator = { '[', ' '};
int n = c.length;
int m = c[0].length;
for (int i = 0; i < n; i++) {
separator[0] = '(';
for (int j = 0; j < n; j++) {
sb.append(separator);
sb.append(c[i][j]);
separator[0] = ',';
}
separator[0] = ':';
for (int j = n; j < m; j++) {
sb.append(separator);
sb.append(c[i][j]);
separator[0] = ',';
}
sb.append(')');
sb.append('\n');
}
return sb.toString();
}
/**
* Add two n x n square complex matrices.
* @param a the first square complex matrix
* @param b the second square complex matrix
* @return the sum matrix (a square complex matrix)
*/
public ComplexMat matAddition(ComplexMat a, ComplexMat b) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = a.re[i][j] + b.re[i][j];
c.im[i][j] = a.im[i][j] + b.im[i][j];
}
return c;
}
/**
* Provide the opposite of an n x n square complex matrix.
* @param a the orignal square complex matrix
* @return the opposite square complex matrix
*/
public ComplexMat matOppose(ComplexMat a) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = -a.re[i][j];
c.im[i][j] = -a.im[i][j];
}
return c;
}
//------------------------------------------------------------------//
// Special n x n square complexe matrices involved in spin-echo NMR //
//------------------------------------------------------------------//
/**
* Select a single complex element located at (row, col)
* in an n x n square complex matrix, involved in Hahn echo experiment.
* @param a the original square complex matrix
* @param row a positive integer describing the row of
* the non-zeroed complex element with 0 <= row < n
* @param col a positive integer describing the column of
* the non-zeroed complex element with 0 <= col < n
* @return the square complex matrix with the single non-zoroed element
*/
public ComplexMat matSingleElement(ComplexMat a, int row, int col) {
ComplexMat c = new ComplexMat();
c.re[row][col] = a.re[row][col];
c.im[row][col] = a.im[row][col];
return c;
}
/**
* Select 4 complex elements located at (row, col), (n - row - 1, col),
* (n - row - 1, n - col - 1), and (row, n - col - 1)
* of an n x n square complex matrix, involved in Solomon echo experiment.
* @param a the original square complex matrix
* @param row a positive integer defining the rows
* of the 4 non-zeroed complex elements with 0 <= row < n
* @param col a positive integer defining the columns
* of the 4 non-zeroed complex elements with 0 <= col < n
* @return the 4 non-zeroed element square complex matrix
*/
public ComplexMat matFourElement(ComplexMat a, int row, int col) {
ComplexMat c = new ComplexMat();
//attention les huit ligne de code doivent apparaitre dans cet ordre
//sinon problème avec IE5.5 sous Windows 98
c.re[n - row - 1][col] = a.re[n - row - 1][col];
c.im[n - row - 1][col] = a.im[n - row - 1][col];
c.re[row][col] = a.re[row][col];
c.im[row][col] = a.im[row][col];
c.re[n - row - 1][n - col - 1] = a.re[n - row - 1][n - col - 1];
c.im[n - row - 1][n - col - 1] = a.im[n - row - 1][n - col - 1];
c.re[row][n - col - 1] = a.re[row][n - col - 1];
c.im[row][n - col - 1] = a.im[row][n - col - 1];
return c;
}
/**
* Rotation of an n x n square complex matrix by a phase,
* p-quantum coherence is multiplied by exp(-ip*phase).
* @param a the original square complex matrix
* @param phase a double value describing the phase of the rotation
* @return the rotated square complex matrix
*/
public ComplexMat matRotation(ComplexMat a, double phase) {
ComplexMat c = new ComplexMat();
double cs, sn;
for (int i = 0; i < n; i++) {
c.re[i][i] = a.re[i][i];
c.im[i][i] = a.im[i][i];
}
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++) {
cs = Math.cos((j - i)*phase); //column - row, opposite to mathematic convention
sn = Math.sin((j - i)*phase); //exp(-ip*phase) with p = row - column
c.re[i][j] = a.re[i][j]*cs - a.im[i][j]*sn;
c.im[i][j] = a.re[i][j]*sn + a.im[i][j]*cs;
}
for (int j = 0; j < n - 1; j++)
for (int i = j + 1; i < n; i++) {
c.re[i][j] = c.re[j][i];
c.im[i][j] = -c.im[j][i];
}
return c;
}
/**
* Select 2 complex elements of an n x n square complex matrix,
* involved in double-quantum Solomon echo experiment.
* @param a the original square complex matrix
* @param row a positive integer defining the rows
* of the 2 non-zeroed complex elements with 0 <= row < n
* @param col a positive integer defining the columns
* of the 2 non-zeroed complex elements with 0 <= col < n
* @return the 2-non-zeroed element square complex matrix
*/
public ComplexMat matTwoElement(ComplexMat a, int row, int col) {
ComplexMat c = new ComplexMat();
if (((row + col) % 2) == 0) {
c.re[row][col] = a.re[row][col];
c.im[row][col] = a.im[row][col];
c.re[n - row - 1][n - col - 1] = a.re[n - row - 1][n - col - 1];
c.im[n - row - 1][n - col - 1] = a.im[n - row - 1][n - col - 1];
}
else {
c.re[n - row - 1][col] = a.re[n - row - 1][col];
c.im[n - row - 1][col] = a.im[n - row - 1][col];
c.re[row][n - col - 1] = a.re[row][n - col - 1];
c.im[row][n - col - 1] = a.im[row][n - col - 1];
}
return c;
}
/**
* Select even-quantum coherences of an n x n square complex matrix.
* @param a the original square complex matrix
* @return the square complex matrix with zeroed odd-quantum coherences
*/
public ComplexMat matEvenQuantum(ComplexMat a) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = a.re[i][j];
c.im[i][j] = a.im[i][j];
}
for (int i = 0; i < n; i++){
if (i % 2 == 1){
for (int j = 0; j < (n/2); j++) {
c.re[i][2*j] = 0;
c.im[i][2*j] = 0;
}
}
else {
for (int j = 0; j < (n/2); j++) {
c.re[i][2*j + 1] = 0;
c.im[i][2*j + 1] = 0;
}
}
}
return c;
}
/**
* Select odd-quantum coherences of an n x n square complex matrix.
* @param a the original square complex matrix
* @return the square complex matrix with zeroed even-quantum coherences
*/
public ComplexMat matOddQuantum(ComplexMat a) {
ComplexMat c = new ComplexMat();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
c.re[i][j] = a.re[i][j];
c.im[i][j] = a.im[i][j];
}
for (int i = 0; i < n; i++) {
if (i % 2 == 1) {
for (int j = 0; j < (n/2); j++) {
c.re[i][2*j + 1] = 0;
c.im[i][2*j + 1] = 0;
}
}
else {
for (int j = 0; j < (n/2); j++) {
c.re[i][2*j] = 0;
c.im[i][2*j] = 0;
}
}
}
return c;
}
}//end of class ComplexMat