File: SpecularComputation.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (43 lines) | stat: -rw-r--r-- 1,863 bytes parent folder | download | duplicates (2)
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
}