<commit_before>//! This module allows to combine certain operations into one operation. Since one
//! many machines the speed of many DSP operations is limited by the memory bus speed
//! this approach may result in better register and cache usage and thus decrease
//! the pressure on the memory bus. As with all performance hints remember
//! rule number 1: Benchmark your code. This is especially true at this very early
//! state of the library.
//!
//! With this approach we change how we operate on vectors. If you perform
//! `M` operations on a vector with the length `N` you iterate wit hall other methods like this:
//!
//! ```no_run
//! // pseudocode:
//! // for m in M:
//! //  for n in N:
//! //    execute m on n
//! ```
//!
//! with this method the pattern is changed slightly:
//!
//! ```no_run
//! // pseudocode:
//! // for n in N:
//! //  for m in M:
//! //    execute m on n
//! ```
//!
//! Both variants have the same complexity however the second one is beneficial since we
//! have increased locality this way. This should help us by making better use of registers and
//! CPU caches.
//!
//! Only operations can be combined where the result of every element in the vector
//! is independent from any other element in the vector.
//!
//! # Examples
//!
//! ```
//! use std::f32::consts::PI;
//! use basic_dsp_vector::*;
//! use basic_dsp_vector::combined_ops::*;
//! # fn close(left: &[f32], right: &[f32]) {
//! #   assert_eq!(left.len(), right.len());
//! #   for i in 0..left.len() {
//! #       assert!((left[i] - right[i]) < 1e-2);
//! #   }
//! # }
//! let a = RealTimeVector32::from_array(&[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]);
//! let b = RealTimeVector32::from_constant(0.0, 8);
//! let ops = multi_ops2(a, b);
//! let ops = ops.add_ops(|a, b| {
//!     let a = a.scale(2.0 * PI);
//!     let b = b.clone_from(&a);
//!     let a = a.sin();
//!     let b = b.cos();
//!     let a = a.mul(&b).abs();
//!     let a_db = a.log(10.0).scale(10.0);
//!     (a_db, b)
//! });
//! let (a, b) = ops.get().expect("Ignoring error handling in examples");
//! close(&[0.80902, 0.30902, -0.30902, -0.80902, -1.00000, -0.80902, -0.30902, 0.30902],
//! 		  b.real(0..));
//! close(&[-3.2282, -5.3181, -5.3181, -3.2282, -159.1199, -3.2282, -5.3181, -5.3181],
//! 	      a.real(0..));
//! ```
//!

mod operations_enum;
pub use self::operations_enum::*;
mod prepared_ops;
pub use self::prepared_ops::*;
mod multi_ops;
pub use self::multi_ops::*;
mod identifier_ops;
pub use self::identifier_ops::*;

use RealNumber;
use simd_extensions::*;
use multicore_support::*;
use std::ops::Range;
use super::{round_len, ToSliceMut, DspVec, ErrorReason, MetaData, TransRes, Vector,
            RealToComplexTransformsOpsBuffered, ComplexToRealTransformsOps, Buffer, Owner,
            RealOrComplexData, TimeOrFrequencyData, Domain, NumberSpace, DataDomain};
use std::sync::{Arc, Mutex};
use std::fmt;

fn require_complex(is_complex: bool) -> Result<bool, ErrorReason> {
    if is_complex {
        Ok(is_complex)
    } else {
        Err(ErrorReason::InputMustBeComplex)<commit_msg>Fixed doc test. It hasn't been updated for the 0.3->0.4 API changes and only became active as it was moved to the correct position in the previous commit.<commit_after>//! This module allows to combine certain operations into one operation. Since one
//! many machines the speed of many DSP operations is limited by the memory bus speed
//! this approach may result in better register and cache usage and thus decrease
//! the pressure on the memory bus. As with all performance hints remember
//! rule number 1: Benchmark your code. This is especially true at this very early
//! state of the library.
//!
//! With this approach we change how we operate on vectors. If you perform
//! `M` operations on a vector with the length `N` you iterate wit hall other methods like this:
//!
//! ```no_run
//! // pseudocode:
//! // for m in M:
//! //  for n in N:
//! //    execute m on n
//! ```
//!
//! with this method the pattern is changed slightly:
//!
//! ```no_run
//! // pseudocode:
//! // for n in N:
//! //  for m in M:
//! //    execute m on n
//! ```
//!
//! Both variants have the same complexity however the second one is beneficial since we
//! have increased locality this way. This should help us by making better use of registers and
//! CPU caches.
//!
//! Only operations can be combined where the result of every element in the vector
//! is independent from any other element in the vector.
//!
//! # Examples
//!
//! ```
//! use std::f32::consts::PI;
//! use basic_dsp_vector::*;
//! use basic_dsp_vector::combined_ops::*;
//! # fn close(left: &[f32], right: &[f32]) {
//! #   assert_eq!(left.len(), right.len());
//! #   for i in 0..left.len() {
//! #       assert!((left[i] - right[i]) < 1e-2);
//! #   }
//! # }
//! let a = vec!(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8).to_real_time_vec();
//! let b = vec!(0.0; 8).to_real_time_vec();
//! let ops = multi_ops2(a, b);
//! let ops = ops.add_ops(|mut a, mut b| {
//!     a.scale(2.0 * PI);
//!     b.clone_from(&a);
//!     a.sin();
//!     b.cos();
//!     a.mul(&b);
//!     a.abs();
//!     a.log(10.0);
//!     a.scale(10.0);
//!     (a, b)
//! });
//! let mut buffer = SingleBuffer::new();
//! let (a, b) = ops.get(&mut buffer).expect("Ignoring error handling in examples");
//! close(&[0.80902, 0.30902, -0.30902, -0.80902, -1.00000, -0.80902, -0.30902, 0.30902],
//! 		  &b[..]);
//! close(&[-3.2282, -5.3181, -5.3181, -3.2282, -159.1199, -3.2282, -5.3181, -5.3181],
//! 	      &a[..]);
//! ```
//!

mod operations_enum;
pub use self::operations_enum::*;
mod prepared_ops;
pub use self::prepared_ops::*;
mod multi_ops;
pub use self::multi_ops::*;
mod identifier_ops;
pub use self::identifier_ops::*;

use RealNumber;
use simd_extensions::*;
use multicore_support::*;
use std::ops::Range;
use super::{round_len, ToSliceMut, DspVec, ErrorReason, MetaData, TransRes, Vector,
            RealToComplexTransformsOpsBuffered, ComplexToRealTransformsOps, Buffer, Owner,
            RealOrComplexData, TimeOrFrequencyData, Domain, NumberSpace, DataDomain};
use std::sync::{Arc, Mutex};
use std::fmt;

fn require_complex(is_complex: bool) -> Result<bool, ErrorReason> {
    if is_complex {
        Ok(is_complex)
    } else {
        Err(ErrorReason::InputMustBeComplex)
{'fraction_non_alphanumeric': 0.1870253164556962, 'fraction_numerical': 0.04208860759493671, 'mean_word_length': 2.965495608531995, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '923330', 'n_tokens_mistral': 2370, 'n_tokens_neox': 2101, 'n_words': 707}