/// <summary>
        /// Evaluate the stationary radially resolved z-flux with the point source-image
        /// configuration
        /// </summary>
        /// <param name="rho">radial location</param>
        /// <param name="z">depth location</param>
        /// <param name="dp">DiffusionParameters for layer 1 and 2</param>
        /// <param name="layerThicknesses">thickness of top layer, array but only need first element</param>
        /// <returns></returns>
        private static double StationaryFlux(double rho, double z, DiffusionParameters[] dp, double[] layerThicknesses)
        {
            var    layerThickness = layerThicknesses[0];
            double flux;

            if (z < layerThickness) // top layer dphi1/dz solution
            {
                flux = HankelTransform.DigitalFilterOfOrderZero(rho, s => dPhi1(s, z, dp, layerThicknesses));
            }
            else // bottom layer phi2/dz solution
            {
                flux = HankelTransform.DigitalFilterOfOrderZero(rho, s => dPhi2(s, z, dp, layerThicknesses));
            }
            return(flux / (2 * Math.PI));
        }
 public override IEnumerable <double> ROfFxAndTime(
     IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs, IEnumerable <double> ts)
 {
     foreach (var op in ops)
     {
         foreach (var fx in fxs)
         {
             foreach (var t in ts)
             {
                 yield return
                     (2 * Math.PI *
                      HankelTransform.DigitalFilterOfOrderZero(
                          2 * Math.PI * fx, rho => ROfRhoAndTime(op, rho, t)));
             }
         }
     }
 }
 public override IEnumerable <double> FluenceOfFxAndZAndTime(
     IEnumerable <OpticalProperties> ops,
     IEnumerable <double> fxs,
     IEnumerable <double> zs,
     IEnumerable <double> ts)
 {
     foreach (var op in ops)
     {
         DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel);
         foreach (var fx in fxs)
         {
             foreach (var z in zs)
             {
                 foreach (var t in ts)
                 {
                     yield return
                         (HankelTransform.DigitalFilterOfOrderZero(
                              fx, rho => TemporalFluence(dp, rho, z, t)));
                 }
             }
         }
     }
 }
        public static Complex TemporalFrequencyZFlux(double rho, double z, double temporalFrequency,
                                                     DiffusionParameters[] dp, double[] layerThicknesses)
        {
            var     layerThickness = layerThicknesses[0];
            Complex flux;

            if (z < layerThickness) // top layer dphi1/dz solution
            {
                flux = HankelTransform.DigitalFilterOfOrderZero(
                    rho, s => TemporalFrequencydPhi1(s, z, temporalFrequency, dp, layerThicknesses).Real) +
                       HankelTransform.DigitalFilterOfOrderZero(
                    rho, s => TemporalFrequencydPhi1(s, z, temporalFrequency, dp, layerThicknesses).Imaginary) *
                       Complex.ImaginaryOne;
            }
            else // bottom layer phi2/dz solution
            {
                flux = HankelTransform.DigitalFilterOfOrderZero(
                    rho, s => TemporalFrequencydPhi2(s, z, temporalFrequency, dp, layerThicknesses).Real) +
                       HankelTransform.DigitalFilterOfOrderZero(
                    rho, s => TemporalFrequencydPhi2(s, z, temporalFrequency, dp, layerThicknesses).Imaginary) *
                       Complex.ImaginaryOne;
            }
            return(flux / (2 * Math.PI));
        }