/* TA-LIB Copyright (c) 1999-2025, Mario Fortier
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * - Neither name of author nor the names of its contributors
 *   may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Important:
 *  This file is automatically generated by the utility ta_codegen.
 *  Any modifications will be lost on next execution of ta_codegen.
 *
 *  Modifications should instead be done with the "C" source file
 *  in ta-lib\src\ta_func
 */

/* List of contributors:
 *
 *  Initial  Name/description
 *  -------------------------------------------------------------------
 *  MF       Mario Fortier
 *  JV       Jesus Viver <324122@cienz.unizar.es>
 *
 *
 * Change history:
 *
 *  MMDDYY BY   Description
 *  -------------------------------------------------------------------
 *  112400 MF   Template creation.
 *  010503 MF   Fix to always use SMA for the STDDEV (Thanks to JV).
 *  052603 MF   Adapt code to compile with .NET Managed C++
 */

// Import types from parent module
use super::*;

// Allow non-snake-case names to maintain TA-Lib API compatibility
#[allow(non_snake_case)]
#[allow(unused_variables)]
#[allow(dead_code)]
#[allow(unused_mut)]
#[allow(unused_assignments)]
impl Core {
    /// Lookback period for [`Core::bbands`]: the number of leading input values consumed before the
    /// first output value can be produced.
    ///
    /// # Arguments
    ///
    /// * `optInTimePeriod` — Periods for the MA and standard deviation (default 5, range
    ///   2..=100000)
    /// * `optInNbDevUp` — Standard-deviation multiplier for the upper band (default 2)
    /// * `optInNbDevDn` — Standard-deviation multiplier for the lower band (default 2)
    /// * `optInMAType` — Moving-average type for the middle band (default 0 = SMA, values: 0=SMA,
    ///   1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3)
    ///
    /// Returns `usize::MAX` when a parameter is out of range. Integer parameters accept `i32::MIN`
    /// to select their default value.
    #[inline]
    pub fn bbands_lookback(&self, mut optInTimePeriod: i32, mut optInNbDevUp: f64, mut optInNbDevDn: f64, mut optInMAType: i32) -> usize {
        if ((optInTimePeriod) as i32) == (i32::MIN) {
            optInTimePeriod = 5;
        } else if (((optInTimePeriod) as i32) < 2) || (((optInTimePeriod) as i32) > 100000) {
            return usize::MAX;
        }
        // The lookback is driven by the middle band moving average.
        return self.ma_lookback(optInTimePeriod, optInMAType);
    }
    /// Bollinger Bands: a moving-average middle band with upper and lower bands offset by a
    /// multiple of the standard deviation. Used to gauge relative price volatility.
    ///
    /// # Formula
    ///
    /// ```text
    /// middle = MA(inReal, period); sd = stddev(inReal, period); upper = middle + nbDevUp*sd; lower = middle - nbDevDn*sd
    /// ```
    ///
    /// # Notes
    ///
    /// * The standard deviation uses the population form (dividing by the period), not the sample
    ///   form.
    /// * The standard deviation is always computed with a simple moving average regardless of the
    ///   selected MA type.
    ///
    /// # Arguments
    ///
    /// * `startIdx` — Start index of the requested calculation range.
    /// * `endIdx` — End index of the requested calculation range (inclusive).
    /// * `inReal` — Input data series.
    /// * `optInTimePeriod` — Periods for the MA and standard deviation (default 5, range
    ///   2..=100000)
    /// * `optInNbDevUp` — Standard-deviation multiplier for the upper band (default 2)
    /// * `optInNbDevDn` — Standard-deviation multiplier for the lower band (default 2)
    /// * `optInMAType` — Moving-average type for the middle band (default 0 = SMA, values: 0=SMA,
    ///   1=EMA, 2=WMA, 3=DEMA, 4=TEMA, 5=TRIMA, 6=KAMA, 7=MAMA, 8=T3)
    /// * `outBegIdx` — Set to the input index of the first output value.
    /// * `outNBElement` — Set to the number of output values written.
    /// * `outRealUpperBand` — Middle band plus nbDevUp standard deviations.
    /// * `outRealMiddleBand` — The moving average.
    /// * `outRealLowerBand` — Middle band minus nbDevDn standard deviations.
    ///
    /// Integer parameters accept `i32::MIN` to select their default value.
    ///
    /// # Errors
    ///
    /// Returns [`RetCode::OutOfRangeStartIndex`] when `endIdx < startIdx`, and
    /// [`RetCode::BadParam`] when an optional parameter is outside its documented range.
    ///
    /// # Panics
    ///
    /// Input slices must cover `startIdx..=endIdx` and output slices must hold the number of values
    /// produced for that range: undersized slices panic or, for functions that forward to unchecked
    /// internals, cause undefined behavior. Sizing every output slice to the input length is always
    /// sufficient.
    ///
    /// # Examples
    ///
    /// ```
    /// use ta_lib::{Core, RetCode};
    ///
    /// let data: Vec<f64> = (0..252).map(|i| 100.0 + 10.0 * (0.1 * i as f64).sin()).collect();
    ///
    /// let core = Core::new();
    /// let mut out_beg = 0;
    /// let mut out_nb = 0;
    /// let mut upper_band = vec![0.0; 252];
    /// let mut middle_band = vec![0.0; 252];
    /// let mut lower_band = vec![0.0; 252];
    ///
    /// let ret = core.bbands(
    ///     0, data.len() - 1, &data, 5, 2.0, 2.0, 0,
    ///     &mut out_beg, &mut out_nb, &mut upper_band, &mut middle_band, &mut lower_band,
    /// );
    /// assert_eq!(ret, RetCode::Success);
    /// assert!(out_nb > 0);
    /// ```
    ///
    /// # See also
    ///
    /// [`Core::ma`] · [`Core::stddev`] · [`Core::sma`]
    ///
    /// # References
    ///
    /// * John A. Bollinger, *Bollinger on Bollinger Bands*, McGraw-Hill Trade (ISBN 0071373683)
    ///
    /// Further reading: [ta-lib.org/functions/bbands](https://ta-lib.org/functions/bbands/)
    #[doc(alias = "BollingerBands")]
    pub fn bbands(
        &self,
        startIdx: usize,
        endIdx: usize,
        inReal: &[f64],
        mut optInTimePeriod: i32,
        mut optInNbDevUp: f64,
        mut optInNbDevDn: f64,
        mut optInMAType: i32,
        outBegIdx: &mut usize,
        outNBElement: &mut usize,
        outRealUpperBand: &mut [f64],
        outRealMiddleBand: &mut [f64],
        outRealLowerBand: &mut [f64],
    ) -> RetCode {
        if endIdx < startIdx {
            return RetCode::OutOfRangeStartIndex;
        }
        if ((optInTimePeriod) as i32) == (i32::MIN) {
            optInTimePeriod = 5;
        } else if (((optInTimePeriod) as i32) < 2) || (((optInTimePeriod) as i32) > 100000) {
            return RetCode::BadParam;
        }
        let mut startIdx = startIdx;
        let mut retCode: RetCode = RetCode::Success;
        let mut i: usize = 0_usize;
        let mut tempReal: f64 = 0.0_f64;
        let mut tempReal2: f64 = 0.0_f64;
        let mut tempBuffer1: Vec<f64> = Vec::new();
        let mut tempBuffer2: Vec<f64> = Vec::new();
        // Identify TWO temporary buffer among the outputs.
        //
        // These temporary buffers allows to perform the
        // calculation without any memory allocation.
        //
        // Whenever possible, make the tempBuffer1 be the
        // middle band output. This will save one copy operation.
        if inReal.as_ptr() == outRealUpperBand.as_ptr() {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealLowerBand.to_vec();
        } else if inReal.as_ptr() == outRealLowerBand.as_ptr() {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        } else if inReal.as_ptr() == outRealMiddleBand.as_ptr() {
            tempBuffer1 = outRealLowerBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        } else {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        }
        // Check that the caller is not doing tricky things.
        // (like using the input buffer in two output!)
        if tempBuffer1.as_ptr() == inReal.as_ptr() || tempBuffer2.as_ptr() == inReal.as_ptr() {
            return RetCode::BadParam;
        }
        // Calculate the middle band, which is a moving average.
        // The other two bands will simply add/substract the
        // standard deviation from this middle band.
        retCode = self.ma_unguarded(startIdx, endIdx, inReal, optInTimePeriod, optInMAType, outBegIdx, outNBElement, &mut tempBuffer1[..]);
        if retCode != RetCode::Success || ((*outNBElement) as usize) == 0 {
            (*outNBElement) = 0;
            return retCode;
        }
        // Calculate the standard deviation into tempBuffer2.
        if (optInMAType) as usize == 0 {
            // A small speed optimization by re-using the
            // already calculated SMA.
            // Inline stddev_using_precalc_ma
            let mut _tempReal: f64 = 0.0_f64;
            let mut _periodTotal2: f64 = 0.0_f64;
            let mut _meanValue2: f64 = 0.0_f64;
            let mut _outIdx: usize = 0_usize;
            let mut _startSum: usize = 0_usize;
            let mut _endSum: usize = 0_usize;
            _startSum = (1 + ((*outBegIdx) as usize) - (optInTimePeriod) as usize) as usize;
            _endSum = ((*outBegIdx) as usize) as usize;
            _periodTotal2 = 0.0;
            // for( _outIdx = _startSum; _outIdx < _endSum; _outIdx += 1 )
            _outIdx = _startSum;
            while _outIdx < _endSum {
                _tempReal = inReal[_outIdx];
                _tempReal *= _tempReal;
                _periodTotal2 += _tempReal;
                _outIdx += 1;
            }
            // for( _outIdx = 0; _outIdx < (((*outNBElement) as usize)) as usize; _outIdx += 1, _startSum += 1, _endSum += 1 )
            _outIdx = 0;
            while _outIdx < (((*outNBElement) as usize)) as usize {
                _tempReal = inReal[_endSum];
                _tempReal *= _tempReal;
                _periodTotal2 += _tempReal;
                _meanValue2 = _periodTotal2 / ((optInTimePeriod) as f64);
                _tempReal = inReal[_startSum];
                _tempReal *= _tempReal;
                _periodTotal2 -= _tempReal;
                _tempReal = tempBuffer1[_outIdx];
                _tempReal *= _tempReal;
                _meanValue2 -= _tempReal;
                if !((_meanValue2) < 1e-14) {
                    tempBuffer2[_outIdx] = (_meanValue2).sqrt();
                } else {
                    tempBuffer2[_outIdx] = 0.0;
                }
                _outIdx += 1;
                _startSum += 1;
                _endSum += 1;
            }
        } else {
            // Calculate the Standard Deviation
            retCode = self.stddev_unguarded(((*outBegIdx) as usize) as usize, endIdx, inReal, optInTimePeriod, 1.0, outBegIdx, outNBElement, &mut tempBuffer2[..]);
            if retCode != RetCode::Success {
                (*outNBElement) = 0;
                return retCode;
            }
        }
        // Copy the MA calculation into the middle band ouput, unless
        // the calculation was done into it already!
        if tempBuffer1.as_ptr() != outRealMiddleBand.as_ptr() {
            {
            let _n = ((*outNBElement) * 1) as usize;
            let _di = (0) as usize;
            let _si = (0) as usize;
            outRealMiddleBand[_di.._di + _n].copy_from_slice(&tempBuffer1[_si.._si + _n]);
        };
        }
        // Now do a tight loop to calculate the upper/lower band at
        // the same time.
        //
        // All the following 5 loops are doing the same, except there
        // is an attempt to speed optimize by eliminating uneeded
        // multiplication.
        if optInNbDevUp == optInNbDevDn {
            if optInNbDevUp == 1.0 {
                // No standard deviation multiplier needed.
                // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
                i = 0;
                while i < (((*outNBElement) as usize)) as usize {
                    tempReal = tempBuffer2[i];
                    tempReal2 = outRealMiddleBand[i];
                    outRealUpperBand[i] = tempReal2 + tempReal;
                    outRealLowerBand[i] = tempReal2 - tempReal;
                    i += 1;
                }
            } else {
                // Upper/lower band use the same standard deviation multiplier.
                // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
                i = 0;
                while i < (((*outNBElement) as usize)) as usize {
                    tempReal = tempBuffer2[i] * optInNbDevUp;
                    tempReal2 = outRealMiddleBand[i];
                    outRealUpperBand[i] = tempReal2 + tempReal;
                    outRealLowerBand[i] = tempReal2 - tempReal;
                    i += 1;
                }
            }
        } else if optInNbDevUp == 1.0 {
            // Only lower band has a standard deviation multiplier.
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = tempBuffer2[i];
                tempReal2 = outRealMiddleBand[i];
                outRealUpperBand[i] = tempReal2 + tempReal;
                outRealLowerBand[i] = tempReal2 - tempReal * optInNbDevDn;
                i += 1;
            }
        } else if optInNbDevDn == 1.0 {
            // Only upper band has a standard deviation multiplier.
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = tempBuffer2[i];
                tempReal2 = outRealMiddleBand[i];
                outRealLowerBand[i] = tempReal2 - tempReal;
                outRealUpperBand[i] = (tempReal as f64).mul_add(optInNbDevUp, tempReal2);
                i += 1;
            }
        } else {
            // Upper/lower band have distinctive standard deviation multiplier.
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = tempBuffer2[i];
                tempReal2 = outRealMiddleBand[i];
                outRealUpperBand[i] = (tempReal as f64).mul_add(optInNbDevUp, tempReal2);
                outRealLowerBand[i] = tempReal2 - tempReal * optInNbDevDn;
                i += 1;
            }
        }
        return RetCode::Success;
    }
    /// Unchecked variant of [`Core::bbands`], used for internal cross-indicator calls.
    ///
    /// Skips parameter validation and uses unchecked indexing internally. Every argument must
    /// satisfy the constraints documented on [`Core::bbands`]; an out-of-range parameter, an input
    /// slice not covering `startIdx..=endIdx`, or an undersized output slice may panic or cause
    /// undefined behavior. Prefer [`Core::bbands`].
    #[inline]
    pub fn bbands_unguarded(
        &self,
        mut startIdx: usize,
        endIdx: usize,
        inReal: &[f64],
        mut optInTimePeriod: i32,
        mut optInNbDevUp: f64,
        mut optInNbDevDn: f64,
        mut optInMAType: i32,
        outBegIdx: &mut usize,
        outNBElement: &mut usize,
        outRealUpperBand: &mut [f64],
        outRealMiddleBand: &mut [f64],
        outRealLowerBand: &mut [f64],
    ) -> RetCode {
        let mut retCode: RetCode = RetCode::Success;
        let mut i: usize = 0_usize;
        let mut tempReal: f64 = 0.0_f64;
        let mut tempReal2: f64 = 0.0_f64;
        let mut tempBuffer1: Vec<f64> = Vec::new();
        let mut tempBuffer2: Vec<f64> = Vec::new();
        unsafe {
        assert!(endIdx < inReal.len());
        let _assertLb = self.bbands_lookback(optInTimePeriod, optInNbDevUp, optInNbDevDn, optInMAType);
        let _assertStart = if startIdx > _assertLb { startIdx } else { _assertLb };
        assert!(_assertStart > endIdx || endIdx - _assertStart < outRealUpperBand.len());
        assert!(_assertStart > endIdx || endIdx - _assertStart < outRealMiddleBand.len());
        assert!(_assertStart > endIdx || endIdx - _assertStart < outRealLowerBand.len());
        if inReal.as_ptr() == outRealUpperBand.as_ptr() {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealLowerBand.to_vec();
        } else if inReal.as_ptr() == outRealLowerBand.as_ptr() {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        } else if inReal.as_ptr() == outRealMiddleBand.as_ptr() {
            tempBuffer1 = outRealLowerBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        } else {
            tempBuffer1 = outRealMiddleBand.to_vec();
            tempBuffer2 = outRealUpperBand.to_vec();
        }
        if tempBuffer1.as_ptr() == inReal.as_ptr() || tempBuffer2.as_ptr() == inReal.as_ptr() {
            return RetCode::BadParam;
        }
        retCode = self.ma_unguarded(startIdx, endIdx, inReal, optInTimePeriod, optInMAType, outBegIdx, outNBElement, &mut tempBuffer1[..]);
        if retCode != RetCode::Success || ((*outNBElement) as usize) == 0 {
            (*outNBElement) = 0;
            return retCode;
        }
        if (optInMAType) as usize == 0 {
            let mut _tempReal: f64 = 0.0_f64;
            let mut _periodTotal2: f64 = 0.0_f64;
            let mut _meanValue2: f64 = 0.0_f64;
            let mut _outIdx: usize = 0_usize;
            let mut _startSum: usize = 0_usize;
            let mut _endSum: usize = 0_usize;
            _startSum = (1 + ((*outBegIdx) as usize) - (optInTimePeriod) as usize) as usize;
            _endSum = ((*outBegIdx) as usize) as usize;
            _periodTotal2 = 0.0;
            // for( _outIdx = _startSum; _outIdx < _endSum; _outIdx += 1 )
            _outIdx = _startSum;
            while _outIdx < _endSum {
                _tempReal = *inReal.as_ptr().add(_outIdx);
                _tempReal *= _tempReal;
                _periodTotal2 += _tempReal;
                _outIdx += 1;
            }
            // for( _outIdx = 0; _outIdx < (((*outNBElement) as usize)) as usize; _outIdx += 1, _startSum += 1, _endSum += 1 )
            _outIdx = 0;
            while _outIdx < (((*outNBElement) as usize)) as usize {
                _tempReal = *inReal.as_ptr().add(_endSum);
                _tempReal *= _tempReal;
                _periodTotal2 += _tempReal;
                _meanValue2 = _periodTotal2 / ((optInTimePeriod) as f64);
                _tempReal = *inReal.as_ptr().add(_startSum);
                _tempReal *= _tempReal;
                _periodTotal2 -= _tempReal;
                _tempReal = *tempBuffer1.as_ptr().add(_outIdx);
                _tempReal *= _tempReal;
                _meanValue2 -= _tempReal;
                if !((_meanValue2) < 1e-14) {
                    *tempBuffer2.as_mut_ptr().add(_outIdx) = (_meanValue2).sqrt();
                } else {
                    *tempBuffer2.as_mut_ptr().add(_outIdx) = 0.0;
                }
                _outIdx += 1;
                _startSum += 1;
                _endSum += 1;
            }
        } else {
            retCode = self.stddev_unguarded(((*outBegIdx) as usize) as usize, endIdx, inReal, optInTimePeriod, 1.0, outBegIdx, outNBElement, &mut tempBuffer2[..]);
            if retCode != RetCode::Success {
                (*outNBElement) = 0;
                return retCode;
            }
        }
        if tempBuffer1.as_ptr() != outRealMiddleBand.as_ptr() {
            {
            let _n = ((*outNBElement) * 1) as usize;
            let _di = (0) as usize;
            let _si = (0) as usize;
            outRealMiddleBand[_di.._di + _n].copy_from_slice(&tempBuffer1[_si.._si + _n]);
        };
        }
        if optInNbDevUp == optInNbDevDn {
            if optInNbDevUp == 1.0 {
                // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
                i = 0;
                while i < (((*outNBElement) as usize)) as usize {
                    tempReal = *tempBuffer2.as_ptr().add(i);
                    tempReal2 = *outRealMiddleBand.as_ptr().add(i);
                    *outRealUpperBand.as_mut_ptr().add(i) = tempReal2 + tempReal;
                    *outRealLowerBand.as_mut_ptr().add(i) = tempReal2 - tempReal;
                    i += 1;
                }
            } else {
                // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
                i = 0;
                while i < (((*outNBElement) as usize)) as usize {
                    tempReal = *tempBuffer2.as_ptr().add(i) * optInNbDevUp;
                    tempReal2 = *outRealMiddleBand.as_ptr().add(i);
                    *outRealUpperBand.as_mut_ptr().add(i) = tempReal2 + tempReal;
                    *outRealLowerBand.as_mut_ptr().add(i) = tempReal2 - tempReal;
                    i += 1;
                }
            }
        } else if optInNbDevUp == 1.0 {
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = *tempBuffer2.as_ptr().add(i);
                tempReal2 = *outRealMiddleBand.as_ptr().add(i);
                *outRealUpperBand.as_mut_ptr().add(i) = tempReal2 + tempReal;
                *outRealLowerBand.as_mut_ptr().add(i) = tempReal2 - tempReal * optInNbDevDn;
                i += 1;
            }
        } else if optInNbDevDn == 1.0 {
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = *tempBuffer2.as_ptr().add(i);
                tempReal2 = *outRealMiddleBand.as_ptr().add(i);
                *outRealLowerBand.as_mut_ptr().add(i) = tempReal2 - tempReal;
                *outRealUpperBand.as_mut_ptr().add(i) = (tempReal as f64).mul_add(optInNbDevUp, tempReal2);
                i += 1;
            }
        } else {
            // for( i = 0; i < (((*outNBElement) as usize)) as usize; i += 1 )
            i = 0;
            while i < (((*outNBElement) as usize)) as usize {
                tempReal = *tempBuffer2.as_ptr().add(i);
                tempReal2 = *outRealMiddleBand.as_ptr().add(i);
                *outRealUpperBand.as_mut_ptr().add(i) = (tempReal as f64).mul_add(optInNbDevUp, tempReal2);
                *outRealLowerBand.as_mut_ptr().add(i) = tempReal2 - tempReal * optInNbDevDn;
                i += 1;
            }
        }
        return RetCode::Success;
        } // unsafe
    }
}
/***************/
/* End of File */
/***************/
