⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 complexarray.cs

📁 C#写的复数和傅立叶变换算法
💻 CS
📖 第 1 页 / 共 2 页
字号:
/*
 * BSD Licence:
 * Copyright (c) 2001, 2002 Ben Houston [ ben@exocortex.org ]
 * Exocortex Technologies [ www.exocortex.org ]
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, 
 * this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name of the <ORGANIZATION> 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.
 */


using System;
using System.Diagnostics;
using Exocortex.DSP;

namespace Exocortex.DSP {
	
	// Comments? Questions? Bugs? Tell Ben Houston at ben@exocortex.org
	// Version: May 4, 2002
	
	/// <summary>
	/// <p>A set of array utilities for complex number arrays</p>
	/// </summary>
	public class ComplexArray {

		//---------------------------------------------------------------------------------------------

		private ComplexArray() {
		}

		//---------------------------------------------------------------------------------------------

		/// <summary>
		/// Clamp length (modulus) of the elements in the complex array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="fMinimum"></param>
		/// <param name="fMaximum"></param>
		static public void ClampLength( Complex[] array, double fMinimum, double fMaximum ) {
			for( int i = 0; i < array.Length; i ++ ) {
				array[i] = Complex.FromModulusArgument( Math.Max( fMinimum, Math.Min( fMaximum, array[i].GetModulus() ) ), array[i].GetArgument() );
			}
		}

		/// <summary>
		/// Clamp elements in the complex array to range [minimum,maximum]
		/// </summary>
		/// <param name="array"></param>
		/// <param name="minimum"></param>
		/// <param name="maximum"></param>
		static public void Clamp( Complex[] array, Complex minimum, Complex maximum ) {
			for( int i = 0; i < array.Length; i ++ ) {
				array[i].Re	= Math.Min( Math.Max( array[ i ].Re, minimum.Re ), maximum.Re );
				array[i].Im	= Math.Min( Math.Max( array[ i ].Re, minimum.Im ), maximum.Im );
			}
		}

		/// <summary>
		/// Clamp elements in the complex array to real unit range (i.e. [0,1])
		/// </summary>
		/// <param name="array"></param>
		static public void ClampToRealUnit( Complex[] array ) {
			for( int i = 0; i < array.Length; i ++ ) {
				array[i].Re =  Math.Min( Math.Max( array[i].Re, 0 ), 1 );
				array[i].Im = 0;
			}
		}
		
		//---------------------------------------------------------------------------------------------

		static private bool			_workspaceFLocked	= false;
		static private ComplexF[]	_workspaceF			= new ComplexF[ 0 ];

		static private void		LockWorkspaceF( int length, ref ComplexF[] workspace ) {
			Debug.Assert( _workspaceFLocked == false );
			_workspaceFLocked = true;
			if( length >= _workspaceF.Length ) {
				_workspaceF	= new ComplexF[ length ];
			}
			workspace =	_workspaceF;
		}
		static private void		UnlockWorkspaceF( ref ComplexF[] workspace ) {
			Debug.Assert( _workspaceF == workspace );
			Debug.Assert( _workspaceFLocked == true );
			_workspaceFLocked = false;
			workspace = null;
		}

		//---------------------------------------------------------------------------------------------

		/// <summary>
		/// Shift (offset) the elements in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Shift( Complex[] array, int offset ) {
			Debug.Assert( array != null );
			Debug.Assert( offset >= 0 );
			Debug.Assert( offset < array.Length );

			if( offset == 0 ) {
				return;
			}

			int			length	= array.Length;
			Complex[]	temp	= new Complex[ length ];

			for( int i = 0; i < length; i ++ ) {
				temp[ ( i + offset ) % length ] = array[ i ];
			}
			for( int i = 0; i < length; i ++ ) {
				array[ i ] = temp[ i ];
			}
		}

		/// <summary>
		/// Shift (offset) the elements in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Shift( ComplexF[] array, int offset ) {
			Debug.Assert( array != null );
			Debug.Assert( offset >= 0 );
			Debug.Assert( offset < array.Length );

			if( offset == 0 ) {
				return;
			}

			int			length		= array.Length;
			ComplexF[]	workspace	= null;
			ComplexArray.LockWorkspaceF( length, ref workspace );

			for( int i = 0; i < length; i ++ ) {
				workspace[ ( i + offset ) % length ] = array[ i ];
			}
			for( int i = 0; i < length; i ++ ) {
				array[ i ] = workspace[ i ];
			}

			ComplexArray.UnlockWorkspaceF( ref workspace );
		}

		//---------------------------------------------------------------------------------------------

		/// <summary>
		/// Get the range of element lengths
		/// </summary>
		/// <param name="array"></param>
		/// <param name="minimum"></param>
		/// <param name="maximum"></param>
		static public void GetLengthRange( Complex[] array, ref double minimum, ref double maximum ) {
			minimum = +double.MaxValue;
			maximum = -double.MaxValue;
			for( int i = 0; i < array.Length; i ++ ) {
				double temp = array[i].GetModulus();
				minimum = Math.Min( temp, minimum );
				maximum = Math.Max( temp, maximum );
			}
		}
		/// <summary>
		/// Get the range of element lengths
		/// </summary>
		/// <param name="array"></param>
		/// <param name="minimum"></param>
		/// <param name="maximum"></param>
		static public void GetLengthRange( ComplexF[] array, ref float minimum, ref float maximum ) {
			minimum = +float.MaxValue;
			maximum = -float.MaxValue;
			for( int i = 0; i < array.Length; i ++ ) {
				float temp = array[i].GetModulus();
				minimum = Math.Min( temp, minimum );
				maximum = Math.Max( temp, maximum );
			}
		}

		// // <summary>
		// // Conver the complex array to a double array
		// // </summary>
		// // <param name="array"></param>
		// // <param name="style"></param>
		// // <returns></returns>
		/* static public double[]	ConvertToDoubleArray( Complex[] array, ConversionStyle style ) {
			double[] newArray = new double[ array.Length ];
			switch( style ) {
			case ConversionStyle.Length:
				for( int i = 0; i < array.Length; i ++ ) {
					newArray[i] = (double) array[i].GetModulus();
				}
				break;
			case ConversionStyle.Real:
				for( int i = 0; i < array.Length; i ++ ) {
					newArray[i] = (double) array[i].Re;
				}
				break;
			case ConversionStyle.Imaginary:
				for( int i = 0; i < array.Length; i ++ ) {
					newArray[i] = (double) array[i].Im;
				}
				break;
			default:
				Debug.Assert( false );
				break;
			}
			return	newArray;
		}	 */

		//---------------------------------------------------------------------------------------------

		/// <summary>
		/// Determine whether the elements in the two arrays are the same
		/// </summary>
		/// <param name="array1"></param>
		/// <param name="array2"></param>
		/// <param name="tolerance"></param>
		/// <returns></returns>
		static public bool		IsEqual( Complex[] array1, Complex[] array2, double tolerance ) {
			if ( array1.Length != array2.Length ) {
				return false;
			}
			for( int i = 0; i < array1.Length; i ++ ) {
				if( Complex.IsEqual( array1[i], array2[i], tolerance ) == false ) {
					return false;
				}
			}
			return true;
		}

		/// <summary>
		///  Determine whether the elements in the two arrays are the same
		/// </summary>
		/// <param name="array1"></param>
		/// <param name="array2"></param>
		/// <param name="tolerance"></param>
		/// <returns></returns>
		static public bool		IsEqual( ComplexF[] array1, ComplexF[] array2, float tolerance ) {
			if ( array1.Length != array2.Length ) {
				return false;
			}
			for( int i = 0; i < array1.Length; i ++ ) {
				if( ComplexF.IsEqual( array1[i], array2[i], tolerance ) == false ) {
					return false;
				}
			}
			return true;
		}

		//---------------------------------------------------------------------------------------------
		
		/// <summary>
		/// Add a specific value to each element in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Offset( Complex[] array, double offset ) {
			int length = array.Length;
			for( int i = 0; i < length; i ++ ) {
				array[i].Re += offset;
			}
		}

		/// <summary>
		/// Add a specific value to each element in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Offset( Complex[] array, Complex offset ) {
			int length = array.Length;
			for( int i = 0; i < length; i ++ ) {
				array[i] += offset;
			}
		}

		/// <summary>
		/// Add a specific value to each element in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Offset( ComplexF[] array, float offset ) {
			int length = array.Length;
			for( int i = 0; i < length; i ++ ) {
				array[i].Re += offset;
			}
		}

		/// <summary>
		/// Add a specific value to each element in the array
		/// </summary>
		/// <param name="array"></param>
		/// <param name="offset"></param>
		static public void Offset( ComplexF[] array, ComplexF offset ) {
			int length = array.Length;
			for( int i = 0; i < length; i ++ ) {
				array[i] += offset;
			}
		}

		//---------------------------------------------------------------------------------------------
		
		/// <summary>
		/// Multiply each element in the array by a specific value
		/// </summary>
		/// <param name="array"></param>
		/// <param name="scale"></param>
		static public void Scale( Complex[] array, double scale ) {
			Debug.Assert( array != null );

			int length = array.Length;
			for( int i = 0; i < length; i ++ ) {
				array[i] *= scale;
			}
		}
		/// <summary>
		///  Multiply each element in the array by a specific value
		/// </summary>
		/// <param name="array"></param>
		/// <param name="scale"></param>
		/// <param name="start"></param>
		/// <param name="length"></param>
		static public void Scale( Complex[] array, double scale, int start, int length ) {
			Debug.Assert( array != null );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -