1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Sim/Computation/SpecularComputation.cpp
//! @brief Implements class SpecularComputation.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Sim/Computation/SpecularComputation.h"
#include "Base/Spin/SpinMatrix.h"
double Compute::magneticR(const SpinMatrix& R, const SpinMatrix& polMatrix,
const SpinMatrix& anaMatrix)
{
// For pure input |i> and output |f> states the measured refl = |<f|R|i>|^2
// If polarizer and analyzer are imperfect (pass different polarizations with some probability)
// we should calculate the following summation: refl = sum{ p_i * p_f * |<f|R|i>|^2 } over
// possible states where 'p_i' and 'p_f' are probabilities of such states |i> and |f>.
// Introducing
// polMatrix = sum{ p_i * |i><i| }
// and
// anaMatrix = sum{ p_f * |f><f| }
// and using identity
// <j|A|j> = tr( |j><j|A )
// we get
// refl = tr( polMatrix * R.adjoint * anaMatrix * R )
const complex_t trace = (polMatrix * R.adjoint() * anaMatrix * R).trace();
// The result represents physically observable value so it has to be real.
// For conversion from complex to real we can take absolute value or real part.
return std::abs(trace);
}
double Compute::scalarR(complex_t R) // Let's keep this function for analogy with magneticR
{
return std::norm(R); // absolute value squared
}
|