[go: up one dir, main page]

CN1790916B - Calibration system for a linearity corrector using filter products - Google Patents

Calibration system for a linearity corrector using filter products Download PDF

Info

Publication number
CN1790916B
CN1790916B CN 200510137332 CN200510137332A CN1790916B CN 1790916 B CN1790916 B CN 1790916B CN 200510137332 CN200510137332 CN 200510137332 CN 200510137332 A CN200510137332 A CN 200510137332A CN 1790916 B CN1790916 B CN 1790916B
Authority
CN
China
Prior art keywords
filter
order
print
frequency
length
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
CN 200510137332
Other languages
Chinese (zh)
Other versions
CN1790916A (en
Inventor
K·R·斯拉文
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tektronix Inc
Original Assignee
Tektronix Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US11/258,237 external-priority patent/US7161515B2/en
Application filed by Tektronix Inc filed Critical Tektronix Inc
Publication of CN1790916A publication Critical patent/CN1790916A/en
Application granted granted Critical
Publication of CN1790916B publication Critical patent/CN1790916B/en
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Images

Landscapes

  • Analogue/Digital Conversion (AREA)
  • Compression, Expansion, Code Conversion, And Decoders (AREA)

Abstract

A calibration system for calibrating a linear corrector using a sum of filter products, and a method of calibrating the linear corrector, are disclosed. The calibration system includes first and second signal generators for introducing a test signal into a signal processing system, such as an ADC. An acquisition memory and processor are provided for acquiring and analyzing the output of the signal processing system, and then programming the filter coefficients into the linearity corrector. The calibration method analyzes intermodulation and harmonic components collected from the signal processing system and then looks for amplitude and phase responses for the filter. The magnitude and phase responses are then used to determine a set of filter coefficients.

Description

使用滤波器乘积的线性校正器的校准系统Calibration system using linearity corrector of filter product

交叉引用  cross reference

本申请要求2004年11月4日提交的申请号为60/625372的美国临时申请的优先权。  This application claims priority to US Provisional Application No. 60/625,372, filed November 4, 2004. the

版权声明  Copyright Notice

依照37 C.E.R.1.71(e),申请人表示,本公开的一部分包含属于和要求版权保护的内容,例如但不限于源码列表、屏幕截图(screen shots)、用户界面、或者用户指令,或者提交的任何其他方面,对这些方面在任何权限中版权保护是或者可能是有用的。本版权所有人对于任何一个专利文件或专利公开文本的传真复制没有异议,例如出现在专利商标局专利文件或记录中。所有其他权利被保留,并且基于本申请或其任何部分的内容、公开显示和公开执行的派生作品的所有其它复制、分发和创建都被适用的版权法所禁止。  Pursuant to 37 C.E.R.1.71(e), applicant represents that a portion of this disclosure contains material that is and claims copyright protection, such as, but not limited to, source code listings, screen shots, user interfaces, or user instructions, or any submitted Other aspects for which copyright protection is or may be useful in any jurisdiction. The copyright owner has no objection to the facsimile reproduction of any of the patent documents or patent disclosures, such as appearing in the Patent and Trademark Office patent files or records. All other rights are reserved and all other reproduction, distribution and creation of derivative works based on the content, public display and public performance of this application or any part thereof are prohibited by applicable copyright laws. the

技术领域 technical field

本发明涉及线性误差校正,尤其涉及一种使用滤波器乘积(filter products)减少或消除由信号处理系统例如模数转换器(ADC)产生的失真的线性校正器。  The present invention relates to linearity error correction, and more particularly to a linearity corrector that uses filter products to reduce or eliminate distortion produced by signal processing systems such as analog-to-digital converters (ADCs). the

背景技术 Background technique

减少ADC所产生的失真增加无寄生动态范围(spurious-free dynamic range)(SFDR),其对于使用ADC来获得数据的系统是有用的,所述系统是例如谱分析器和其他电子测量仪器。  Reducing the distortion produced by the ADC increases spurious-free dynamic range (SFDR), which is useful for systems that use ADCs to acquire data, such as spectrum analyzers and other electronic measurement instruments. the

现代高速ADC设计使用深时钟流水线(deep clock pipeline)来帮助将模拟输入通过一系列改进的步骤精确地转换为采样的数字表示。ADC设计者付出了很大努力来去除模拟处理电路中的明显的非线性源。然而,一般很难去除所有的误差源。设计者试图去除该电路中的最明显的问题直到计算机化建模例如SPICE建模显示该转换器符合技术要求。可以通过使用例如减少非线性装置的动态范围的技术或者使用其周围的反馈来改善线性。然而,一些电路布局具有不能被完全去除的内在失真机制。  Modern high-speed ADC designs use a deep clock pipeline to help accurately convert an analog input into a sampled digital representation in a series of refined steps. ADC designers put a lot of effort into removing significant sources of nonlinearity in the analog processing circuitry. However, it is generally difficult to remove all error sources. Designers try to eliminate the most obvious problems in the circuit until computerized modeling such as SPICE modeling shows that the converter meets specification. Linearity can be improved by using techniques such as reducing the dynamic range of a non-linear device or using feedback around it. However, some circuit topologies have inherent distortion mechanisms that cannot be completely removed. the

流水线处理还为内部数字和模拟电路活动提供对内部模拟信号处理进行调 制的机会。在许多这种情况中,具有自身或其自身衍生物的线性函数的输入信号的自调整产生了残留的非线性失真。这导致了一些难以消除的低水平失真。这种调制可以通过内部电源分配发生。在这种情况下,能够在该电源轨上产生电压调制的电路通道数量可以是相当高。模拟这种效应使得装置建模复杂化并且减缓了计算机模拟。对第一阶来说,对于电源调制的这些影响将会几乎线性增加,所以它们可以作为线性有限脉冲响应(FIR)滤波器建模。  Pipelining also provides the opportunity for internal digital and analog circuit activity to modulate internal analog signal processing. In many such cases, the self-adjustment of the input signal as a linear function of itself or its derivatives produces residual non-linear distortion. This resulted in some low-level distortion that was difficult to remove. This modulation can occur through internal power distribution. In this case, the number of circuit channels capable of producing voltage modulation on that supply rail can be quite high. Simulating this effect complicates device modeling and slows down computer simulations. For the first order, these effects on supply modulation will increase almost linearly, so they can be modeled as linear finite impulse response (FIR) filters. the

在模拟信号处理中的一个或多个点发生调制,其对应于乘法。在流水线ADC中,调制一般发生在转换级之间的高增益模拟放大器中。在这种情况中,典型地该谐波和互调失真的特征在于,存在第2阶和第3阶失真项,其中发生非常少的高阶失真。  Modulation occurs at one or more points in analog signal processing, which correspond to multiplications. In pipeline ADCs, modulation typically occurs in high-gain analog amplifiers between conversion stages. In this case, the harmonic and intermodulation distortion is typically characterized by the presence of 2nd and 3rd order distortion terms, with very little higher order distortion occurring. the

以前提出的解决方案是基于Volterra滤波器的。ADC的脉冲响应可以是许多个时钟周期,例如可以使用64个时钟周期。使用Volterra滤波器的校正系统将需要相似的响应长度。在第3阶失真Volterra系统中,这导致大约(N3)/6抽头的滤波器,其对于具有64响应长度的校正系统将导致大约50000抽头阶。具有这样巨大数量抽头的滤波器系统太复杂和太昂贵以致于当时无法在实际系统中实现。  Previously proposed solutions were based on Volterra filters. The impulse response of the ADC can be many clock periods, for example 64 clock periods can be used. A correction system using a Volterra filter will require a similar response length. In a 3rd order distorted Volterra system, this results in a filter of approximately (N 3 )/6 taps, which for a corrected system with a response length of 64 would result in an order of approximately 50000 taps. Filter systems with such a huge number of taps were too complex and expensive to be realized in practical systems at the time.

在其他与扬声器中的校正失真相关的应用中提出了另一种解决方案,其使用了与Volterra滤波器的某些方面近似的滤波器结构。图1示出了具有第1阶校正和第3阶校正的这种方案的一种型式。第一阶补偿是由滤波器12(h1)来提供的。第三阶补偿是这样提供的,即通过使用乘法器18将滤波器14的输出与滤波器16的输出相乘,使用滤波器20对乘法器18的输出进行过滤,使用乘法器24将滤波器20的输出与滤波器22的输出相乘,最后使用滤波器26对乘法器24的输出进行过滤。通过使用加法器28将来自第一阶补偿的输出和第三阶补偿相加,可以提供线性三次补偿(cubic compensation)。图1中所示系统的第3阶补偿执行下述方程式,  Another solution has been proposed in other applications related to correcting distortion in loudspeakers, which uses a filter structure that approximates some aspects of the Volterra filter. Figure 1 shows a version of this scheme with 1st order correction and 3rd order correction. First order compensation is provided by filter 12(h 1 ). Third order compensation is provided by multiplying the output of filter 14 with the output of filter 16 using multiplier 18, filtering the output of multiplier 18 using filter 20, and multiplying the output of filter The output of 20 is multiplied by the output of filter 22 and finally the output of multiplier 24 is filtered using filter 26 . By adding the output from the first order compensation and the third order compensation using adder 28, linear cubic compensation can be provided. The 3rd order compensation for the system shown in Figure 1 implements the following equation,

Figure S051D7332520060120D000021
Figure S051D7332520060120D000021

Figure S051D7332520060120D000022
Figure S051D7332520060120D000022

其被描述为一般的第3阶非线性滤波器结构。这种实现方案在乘法器18之后使用了滤波器20,以及在乘法器24之后的滤波器26。一旦获得该线性三次补 偿,就从正被补偿的该未知系统的输出中减去。这需要该校正器能眵访问输入到该未知系统的原始信号,而当该原始信号不是数字的时候是不可用的。虽然它可以是Volterra滤波器的有用的子方案,但是它也有不适用于具有良好线性频率响应的系统的缺点。紧接在该乘法器之后的滤波器不能区分原始分量和由在先乘法的非线性效应所引起的混叠分量。虽然该乘法器之后的其他滤波可以提供对于信号通道中的频率相关的幅度和相位响应的一些校正,但是当用于使用大部分Nyquist频带的应用中时,混叠不允许该滤波器对该原始分量和混叠分量之间的相位和幅度响应差进行校正。  It is described as a general 3rd order nonlinear filter structure. This implementation uses filter 20 after multiplier 18 and filter 26 after multiplier 24 . Once the linear cubic compensation is obtained, it is subtracted from the output of the unknown system being compensated. This requires that the corrector have full access to the raw signal input to the unknown system, which is not available when the raw signal is not digital. While it can be a useful sub-solution of the Volterra filter, it also has the disadvantage of not being suitable for systems with a good linear frequency response. Filters immediately following this multiplier cannot distinguish between original components and aliased components caused by the nonlinear effects of previous multiplications. While additional filtering after this multiplier can provide some correction to the frequency-dependent magnitude and phase response in the signal path, aliasing does not allow this filter to reproduce the original The phase and magnitude response differences between the aliased and aliased components are corrected for. the

线性补偿系统中的遗留问题涉及校准。这些系统会需要求解相对于该输出成非线性的滤波器系数的系统。对于任何可以应用到该系统的校准方案,求解更多的系数将需要更多的计算量。  A legacy issue in linear compensation systems involves calibration. These systems would require solving a system of filter coefficients that is nonlinear with respect to the output. For any calibration scheme that can be applied to the system, solving for more coefficients will require more computation. the

在现有解决方案上的细节和改进将在以下更加详细地讨论。  Details and improvements over existing solutions are discussed in more detail below. the

发明内容 Contents of the invention

如果可以通过恢复ADC中的等效失真滤波器的系数来对该失真机制建模,该ADC输出就可以通过以基本上相同的方式使该信号失真的数字处理网络,然后,减去该失真以减少或消除该ADC失真。虽然将所有ADC失真完全消除是不可能的,但是本方法改善了ADC的无寄生动态范围(SFDR)。例如,依赖于该ADC的特性,具有SFDR为80dB的ADC可以改进15dB的因子。本改进还从先前提出的布局中去掉了一些滤波器,从而简化了具有相对平滑线性频率响应的系统使用的设计。这种简化可以对校正系统中的更长滤波器交替使用,从而获得具有相同处理量的改进的性能。该改进对于精确测量应用是有意义的,例如那些与频谱分析器、示波器或者其他使用ADC的测量仪器有关的精确测量应用。  If this distortion mechanism can be modeled by recovering the coefficients of an equivalent distortion filter in an ADC, the ADC output can be passed through a digital processing network that distorts the signal in essentially the same way, and then subtracts the distortion to obtain reduce or eliminate this ADC distortion. Although it is impossible to completely eliminate all ADC distortion, this method improves the spurious-free dynamic range (SFDR) of the ADC. For example, an ADC with an SFDR of 80dB can be improved by a factor of 15dB, depending on the characteristics of the ADC. This improvement also removes some filters from the previously proposed layout, thereby simplifying the design for use in systems with a relatively smooth linear frequency response. This simplification can be alternated with longer filters in the correction system, resulting in improved performance with the same throughput. This improvement is of interest for precision measurement applications, such as those associated with spectrum analyzers, oscilloscopes, or other measurement instruments that use ADCs. the

为了实现这些优点,提供一种合适的校准系统和方法。该校准系统包括:产生第一模拟信号的第一模拟信号产生器,产生第二模拟信号的第二模拟信号产生器,以及连接到该第一模拟信号产生器和第二模拟信号产生器的、用于将该第一模拟信号和第二模拟信号相加并提供模拟输出的模拟加法器。该模拟输出被输入到ADC以获得数字输出。将执行对滤波器乘积求和的线性校正器连接到该ADC的数字输出。在正常操作期间,该线性校正器将提供与该ADC的输出相比具有减小的失真的校正输出。将采集存储器连接到该数字输出;并 且将用于控制该第一信号产生器和第二信号产生器的处理器连接以读取该采集存储器数据。还将该处理器连接到该线性校正器以便为该滤波器乘积编程滤波器系数。  To achieve these advantages, a suitable calibration system and method are provided. The calibration system includes: a first analog signal generator that generates a first analog signal, a second analog signal generator that generates a second analog signal, and connected to the first analog signal generator and the second analog signal generator, An analog adder for adding the first and second analog signals and providing an analog output. This analog output is input to an ADC to obtain a digital output. A linearity corrector, which performs a summation of the filter products, is connected to the digital output of the ADC. During normal operation, the linearity corrector will provide a corrected output with reduced distortion compared to the output of the ADC. An acquisition memory is connected to the digital output; and a processor for controlling the first signal generator and the second signal generator is connected to read the acquisition memory data. The processor is also coupled to the linearity corrector for programming filter coefficients for the filter product. the

还提供了一种校准线性校正器的方法。该校准方法通过将第一波形和第二波形输入到具有输出的信号处理系统来完成。当其中每一个从该信号处理系统中输出时,该采集存储器和处理器采集和分析该第一和第二波形的互调和谐波分量。通过基于失真模型以及该互调和谐波分量来确定目标函数的最小值,寻找连接到该装置输出的线性校正器中使用的滤波器的幅度和相位响应。然后,使用该幅度和相位响应来计算一组滤波器系数。  A method of calibrating a linearity corrector is also provided. The calibration method is accomplished by inputting a first waveform and a second waveform to a signal processing system having an output. The acquisition memory and processor acquire and analyze intermodulation and harmonic components of the first and second waveforms as each is output from the signal processing system. By determining the minimum of the objective function based on the distortion model and the intermodulation and harmonic components, the magnitude and phase response of the filter used in the linearity corrector connected to the output of the device is found. This magnitude and phase response is then used to compute a set of filter coefficients. the

附图说明 Description of drawings

图1(现有技术)是用于补偿扬声器的现有技术的线性校正器的布置的框图。  Figure 1 (Prior Art) is a block diagram of an arrangement of a prior art linearity corrector for compensating loudspeakers. the

图2是包括第1阶、第2阶和第3阶失真的补偿的、基于滤波器乘积的线性校正器的框图。  2 is a block diagram of a filter product based linearity corrector including compensation of 1st order, 2nd order and 3rd order distortion. the

图3是包括第1阶和第3阶失真的补偿的、基于滤波器乘积的线性校正器的框图。  Figure 3 is a block diagram of a filter product based linearity corrector including compensation of 1st and 3rd order distortions. the

图4是包括第1阶、第3阶和第4阶失真的补偿的、基于滤波器乘积的线性校正器的框图。  4 is a block diagram of a filter product based linearity corrector including compensation of 1st order, 3rd order and 4th order distortion. the

图5是补偿ADC的框图。  Figure 5 is a block diagram of a compensated ADC. the

图6是包括补偿和校准系统的ADC系统的框图。  Fig. 6 is a block diagram of an ADC system including a compensation and calibration system. the

图7示出了基本校准过程。  Figure 7 shows the basic calibration process. the

图8示出了该校准过程的附加子步骤。  Figure 8 shows additional sub-steps of the calibration process. the

图9示出了该校准过程的附加子步骤。  Figure 9 shows additional sub-steps of the calibration process. the

图10示出了该校准过程的附加子步骤。  Figure 10 shows additional sub-steps of the calibration process. the

具体实施方式 Detailed ways

本说明书包括第21-51页的用于说明本发明的具体实施例的具体实施方式的示例源代码及其注释文件,文件名称是Slavin.txt。  This specification includes pages 21-51 of the example source code and its annotation file for illustrating the specific implementation of the specific embodiment of the present invention, and the file name is Slavin.txt. the

如上所述,在前提出的解决方案基于Volterra滤波器。然而,由于Volterra滤波器非常大并且很难与ADC一起实现,因此,需要一种解决方案,其利用更易管理的滤波器设计,同时还能够减少一些遗留的主要失真。以Volterra滤 波器作为起始点,广义的非线性滤波器系统能够在数学上定义为:  As mentioned above, the previously proposed solutions are based on Volterra filters. However, since Volterra filters are very large and difficult to implement with ADCs, a solution is needed that utilizes a more manageable filter design while also reducing some of the remaining major distortions. Taking the Volterra filter as a starting point, a generalized nonlinear filter system can be defined mathematically as:

Figure S051D7332520060120D000051
             (方程1) 
Figure S051D7332520060120D000051
(equation 1)

其中,N是该滤波器的脉冲响应长度,k是该滤波器阶指数(order index)。  Wherein, N is the impulse response length of the filter, and k is the order index of the filter. the

例如,如果n=3,则我们有DC值(h0)、k=1时的线性FIR滤波器项、k=2时的2阶失真滤波器以及k=3时的3阶滤波器的和。因而,对于n=3,该Volterra滤波器可以表示为:  For example, if n=3, we have the DC value (h 0 ), the sum of the linear FIR filter term at k=1, the 2nd order distortion filter at k=2 and the 3rd order filter at k=3 . Thus, for n=3, the Volterra filter can be expressed as:

Figure S051D7332520060120D000053
                 (方程2) 
Figure S051D7332520060120D000053
(equation 2)

Volterra滤波器系数与输出y是成线性的,所以理论上,可以利用训练数据来找到一组h。一些乘积项刚好是相同组输入采样的置换(permutations),所以对于每个阶指数k在该组h中的区别值的数量由下式给出,该数量对应于滤波器抽头的数量:  The Volterra filter coefficients are linear with the output y, so in theory, it is possible to use the training data to find a set of h. Some of the product terms happen to be permutations of the same set of input samples, so for each order index k the number of distinct values in the set h is given by the following equation, which corresponds to the number of filter taps:

Figure S051D7332520060120D000054
                (方程3) 
Figure S051D7332520060120D000054
(Equation 3)

遗憾的是,流水线ADC系统的该脉冲响应会是相当大的,所以N可以很大,对于k=3产生很大数量的抽头。例如,如果该流水线ADC系统的脉冲响应是64个时钟周期,从而N=64,那么所需要的抽头数将是大约44000。附加的抽头被需要用于其他阶滤波器,如果存在的话。  Unfortunately, this impulse response of a pipelined ADC system can be quite large, so N can be very large, resulting in a large number of taps for k=3. For example, if the impulse response of the pipelined ADC system is 64 clock cycles, so that N=64, then the number of taps required will be approximately 44000. Additional taps are needed for other order filters, if present. the

现有的ADC线性校正器的实施例依赖于Volterra滤波器系统的子集。该Volterra滤波器系统的子集的特征在于:  Existing embodiments of ADC linearity correctors rely on a subset of the Volterra filter system. A subset of this Volterra filter system is characterized by:

Figure S051D7332520060120D000055
                  (方程4) 
Figure S051D7332520060120D000055
(equation 4)

对于1≤k≤n,系统阶n定义了一组乘积阶。  For 1≤k≤n, the system order n defines a set of product orders. the

尽管抽头的数量和值是未知的,但假定失真模型是这种形式。校正模型具有相同的形式,除非基于具有特定ADC构造的实验,事先选择阶和滤波器的长度。校准则包含找出滤波器抽头。注意到,通常滤波器抽头对于每个滤波器 是不同的。对于系统阶n=3,忽略h0(DC)项,我们得到:  Although the number and value of taps are unknown, the distortion model is assumed to be of this form. The correction model has the same form, except that the order and filter length are chosen in advance based on experiments with a particular ADC configuration. Calibration involves finding the filter taps. Note that in general the filter taps are different for each filter. For system order n=3, ignoring the h 0 (DC) term, we get:

        (方程5)  (equation 5)

这种结构的实施例其特征可以在于,具有使用滤波器实现的每个线性卷积的N抽头滤波器的乘积。  Embodiments of such a structure may be characterized as having a product of N-tap filters implemented using filters for each linear convolution. the

图2示出了用于实现方程式5的线性校正器100的实施例。信号处理系统例如ADC的输出作为输入被提供给该线性校正器100。该线性卷积中的每一个,如方程5中所提供的,使用滤波器102到112来实现。该滤波器可以作为FIR滤波器来实现。第一阶项对应于滤波器102。在可选实施例中,通过用近似等于其他滤波器长度的一半的固定延迟代替滤波器102来获得该第一阶项。在另一实施例中,通过用固定延迟和滤波器的组合代替滤波器102来获得该第一阶项,从而使该总延迟近似为其他阶滤波器长度的一半。通过使用乘法器120将滤波器104和滤波器106的输出相乘以产生二阶滤波器乘积来实现第二阶项。通过使用乘法器122将滤波器108、滤波器110和滤波器112的输出相乘以产生三阶滤波器乘积来实现第三阶。然后,使用加法器124将来自滤波器102的输出与乘法器120和乘法器122的输出相加以提供该滤波器乘积的简单和(simple sum)作为输出。这里使用的术语“简单和”表示将该乘法器的值相加而不需在该乘法器和加法器124之间进行额外滤波的操作。这种简单和通过将该乘法器直接连接到加法器来获得。这里使用的术语直接连接(或者直接被连接)的含义是,在该通道上没有滤波器或其它处理元件,在该通道中可以有不改变通道上信号数据的本质特性的寄存器或其他元件。该输出现在是具有由该信号处理系统例如ADC产生的减少了的非线性的补偿信号。应当注意的是,本发明的实施例消除了现有技术的解决方案中提供的、乘法器之后的滤波器。虽然与图1所示现有技术相比这将需要使用具有额外抽头的滤波器,但是它使得能够使用该滤波器补偿某些失真,而不需要来自该乘法器之后的滤波器的额外补偿。例如,如果图1的现有技术使用了一半时钟周期延迟的全通输出滤波器(所谓sm(x)/x或sinc(x)滤波器),则该滤波器可以被结合到该乘法之前的滤波器中。通过仅在乘法器之前使用滤波器,可能的是该滤波器乘积系统就能够 更好地区分原始分量和混叠分量。  FIG. 2 shows an embodiment of a linearity corrector 100 for implementing Equation 5. Referring to FIG. The output of a signal processing system such as an ADC is provided as input to the linearity corrector 100 . Each of the linear convolutions, as provided in Equation 5, is implemented using filters 102-112. This filter can be implemented as a FIR filter. The first order term corresponds to filter 102 . In an alternative embodiment, this first order term is obtained by replacing filter 102 with a fixed delay approximately equal to half the length of the other filters. In another embodiment, the first order term is obtained by replacing filter 102 with a combination of fixed delays and filters such that the total delay is approximately half the length of the other order filters. The second order term is implemented by multiplying the outputs of filter 104 and filter 106 using multiplier 120 to produce a second order filter product. The third order is achieved by multiplying the outputs of filter 108, filter 110, and filter 112 using multiplier 122 to produce a third order filter product. The output from filter 102 is then added to the outputs of multipliers 120 and 122 using adder 124 to provide a simple sum of the filter products as output. The term "simple sum" as used herein refers to the operation of adding the values of the multiplier without additional filtering between the multiplier and adder 124 . This simplicity is achieved by connecting the multiplier directly to the adder. The term directly connected (or directly connected) is used herein to mean that there are no filters or other processing elements on the path, and there may be registers or other elements in the path that do not alter the essential characteristics of the signal data on the path. The output is now a compensated signal with reduced non-linearity produced by the signal processing system, eg ADC. It should be noted that embodiments of the invention eliminate the filter after the multiplier provided in prior art solutions. While this would require the use of a filter with extra taps compared to the prior art shown in Figure 1, it enables the use of this filter to compensate for some distortion without the need for additional compensation from the filter following the multiplier. For example, if the prior art of Fig. 1 used an all-pass output filter delayed by half a clock cycle (a so-called sm(x)/x or sinc(x) filter), this filter could be incorporated into the filter. By only using a filter before the multiplier, it is possible that the filter product system will be able to better distinguish between original and aliased components. the

虽然在一些实施例中可以通过使用不同长度的滤波器来减少计算量,但是更长长度滤波器的使用会增加在校准期间需要求解的变量的数量,这将会使该校准算法变慢。对于硬件实现,更长长度的滤波器也会需要额外的延迟以匹配该滤波信号延迟。因此,在该校正器100的实施例中,所有滤波器长度都相等。  While in some embodiments the amount of computation can be reduced by using filters of different lengths, the use of longer length filters increases the number of variables that need to be resolved during calibration, which slows down the calibration algorithm. For hardware implementations, filters of longer length would also require additional delays to match the filtered signal delay. Therefore, in this embodiment of the corrector 100, all filters are of equal length. the

图3示出了设计成用于补偿第1阶和第3阶失真而不补偿第2阶失真的线性校正器100的实施例。在一些应用中,第二阶失真显著不到足以证明包括第2阶补偿是有道理的。如图3所示,通过使用乘法器122将滤波器108、滤波器110和滤波器112的输出相乘以产生第三阶滤波器乘积来提供第三阶补偿。然后该第3阶滤波器乘积和第1阶滤波器乘积的简单和可以提供具有减少或者消除了的第1阶和第3阶失真的补偿信号。  FIG. 3 shows an embodiment of a linearity corrector 100 designed to compensate for 1st and 3rd order distortions without compensating for 2nd order distortions. In some applications, the 2nd order distortion is not significant enough to justify including 2nd order compensation. As shown in FIG. 3 , third order compensation is provided by multiplying the outputs of filter 108 , filter 110 , and filter 112 using multiplier 122 to produce a third order filter product. A simple sum of the 3rd order filter product and the 1st order filter product can then provide a compensated signal with reduced or eliminated 1st order and 3rd order distortion. the

如图4所示,能够提供包括第4阶补偿的校正器100的实施例。利用方程4的一般形式,对于系统阶n=4,并且忽略该h0(DC)项,我们就有:  As shown in Figure 4, an embodiment of the corrector 100 including 4th order compensation can be provided. Using the general form of Equation 4, for system order n=4, and neglecting the h 0 (DC) term, we have:

Figure S051D7332520060120D000071
Figure S051D7332520060120D000071

              (方程6)  (equation 6)

如图4所示,该第4阶项可以通过使用乘法器148将滤波器140、滤波器142、滤波器144和滤波器146一起相乘来执行。此外,使用加法器124将该滤波器乘积与其他阶补偿直接求和,而在该乘法器148和加法器124之间没有任何中间滤波器。如从前面例子中可以清楚的,一个本领域普通技术人员将能够求解方程4,以便针对任何预期阶而将其以与方程5和方程6相似的形式放置,其然后可以如这里一般教导地使用滤波器乘积的简单和来实现。如图4所示,第2阶补偿被去除以考虑如下所详细讨论的校准。这种配置将在第4阶具有较大重要性的那些环境中提供补偿。类似地,能够提供对于第4阶和第5阶的补偿并且消除第2阶和第3阶以考虑如下所述的校准。  As shown in FIG. 4 , this 4th order term may be performed by multiplying filter 140 , filter 142 , filter 144 , and filter 146 together using multiplier 148 . Furthermore, the filter product is directly summed with other order compensations using adder 124 without any intermediate filter between the multiplier 148 and adder 124 . As is clear from the preceding examples, one of ordinary skill in the art will be able to solve Equation 4 to place it in a similar form to Equations 5 and 6 for any desired order, which can then be used as generally taught herein A simple sum of filter products is implemented. As shown in Figure 4, the 2nd order compensation is removed to allow for calibration as discussed in detail below. This configuration will provide compensation in those environments where order 4 is of greater importance. Similarly, compensation for 4th and 5th order can be provided and 2nd and 3rd order eliminated to allow for calibration as described below. the

对于所提出的通常的Volterra形式的分解的有效性以及相应的滤波器乘积结构的证明在于理解对于每个乘积阶k存在单一的自调制机制,而不在于任何随机Volterra滤波器系统能够以这种方式被分解的可能性上。 The justification for the validity of the proposed decomposition of the usual Volterra form, and the corresponding filter product structure, lies in the understanding that for each product order k there is a single self-modulation mechanism, not in the fact that any stochastic Volterra filter system is capable of such on the possibility of the way being decomposed.

线性校正器100的各种实施例可以利用专用的硬件执行,例如FPGA或者ASIC,或者利用运行软件的通用处理器执行。当前,尽管运行在通用处理器上的软件对于后采集校正是有用的,但是FPGA或者ASIC对于执行实时校正是有用的。在未来,也有可能为了实时校正利用在通用处理器上的软件。  Various embodiments of linearity corrector 100 may be implemented using dedicated hardware, such as an FPGA or ASIC, or using a general purpose processor running software. Currently, FPGAs or ASICs are useful for performing real-time corrections, although software running on general-purpose processors is useful for post-acquisition corrections. In the future, it will also be possible to utilize software on a general-purpose processor for real-time corrections. the

虽然在一些实施例中,该线性校正器100用于补偿从ADC输出的信号,而在其他实施例中,线性校正器100的结构可以集成在与该ADC相同的封装(packing)中,或者可能集成在与该ADC相同的芯片上,以便形成补偿ADC。该补偿ADC190在图5中示出。它包括ADC模块192,该ADC模块192包含将模拟信号转换成数字信号的各种电路。该ADC模块192的数字输出被输入到可以上述教导实现的线性校正器100。该线性校正器的输出是具有减少了失真的补偿输出。这种组合结构提供了补偿ADC。  Although in some embodiments, the linearity corrector 100 is used to compensate the signal output from the ADC, in other embodiments, the structure of the linearity corrector 100 can be integrated in the same package (packing) as the ADC, or may Integrated on the same chip as this ADC to form a compensating ADC. The compensated ADC 190 is shown in FIG. 5 . It includes an ADC module 192 that contains various circuits that convert analog signals into digital signals. The digital output of the ADC module 192 is input to a linearity corrector 100 which may be implemented with the above teachings. The output of the linearity corrector is a compensated output with reduced distortion. This combined structure provides a compensated ADC. the

为了适当地优化上述线性校正器,有必要对该线性校正器进行校准以对每个滤波器确定合适的滤波器系数。与一般Volterra滤波器不同,图2-4所示的校正器的滤波器乘积输出不是关于其系数成线性的,所以在一般情况下,该滤波器系数的计算是一个非线性优化问题。  In order to properly optimize the linearity corrector described above, it is necessary to calibrate the linearity corrector to determine appropriate filter coefficients for each filter. Unlike the general Volterra filter, the filter product output of the corrector shown in Figure 2-4 is not linear with respect to its coefficients, so in general, the calculation of the filter coefficients is a nonlinear optimization problem. the

因此,提出了一种具有校准的线性校正器系统和一种校准方法。如图6所示,配备有线性校正器100和校准电路的ADC 200。提供模拟选择开关202以控制进入该ADC的输入。该模拟选择开关202由处理器204控制。在校准期间,处理器204控制该模拟选择开关202以允许校准频率信号进入该ADC 200的输入。处理器204还控制数字选择开关206,以控制在校准期间直接来自该ADC 200的数字输出是否进入采集存储器208。处理器204还控制第一校准频率发生器210和第二校准频率发生器212。在校准期间,该第一校准频率发生器210和第二校准频率发生器212的输出在在输入到ADC 200之前,在求和电路214中组合。在本校准方法的实施例中,进入ADC的该模拟校准信号和模拟求和与该被校准的ADC相比具有显著少的失真。  Therefore, a linearity corrector system with calibration and a calibration method are proposed. As shown in FIG. 6, an ADC 200 equipped with a linearity corrector 100 and a calibration circuit. An analog select switch 202 is provided to control the input into the ADC. The analog selection switch 202 is controlled by a processor 204 . During calibration, processor 204 controls the analog select switch 202 to allow a calibration frequency signal to enter the ADC 200 input. Processor 204 also controls digital selector switch 206 to control whether the digital output directly from the ADC 200 goes to acquisition memory 208 during calibration. The processor 204 also controls a first calibration frequency generator 210 and a second calibration frequency generator 212 . During calibration, the outputs of the first calibration frequency generator 210 and the second calibration frequency generator 212 are combined in a summing circuit 214 before being input to the ADC 200. In an embodiment of the calibration method, the analog calibration signal and analog summation into the ADC have significantly less distortion than the ADC being calibrated. the

在校准期间,该采集存储器208采集未校正的ADC输出用于校准。处理在校准频率对的范围上多次采集的数据。该采集的数据由处理器204进行处理。  During calibration, the acquisition memory 208 acquires uncorrected ADC output for calibration. Process data acquired multiple times over a range of calibrated frequency pairs. The collected data is processed by processor 204 . the

在正常操作期间,通过模拟选择开关202将该模拟输入输送到ADC 200,并使用该线性校正器100对该ADC的输出进行校正。该校正器的基本操作已经结合图2-4在上面进行了描述。具有该线性校正器的滤波器可以通过处理 器204加载。然后可以使用第二处理器216提供其他处理,例如可以就像对该ADC的直接输出那样处理该校正的输出。图6所示的实施例示出了用于校准和其他处理的采集存储器208。在可选实施例中,可以使用单独的存储器用于其他处理。类似地,图6所示的实施例示出了第二处理器216,在其他实施例中,处理器204能够提供这种额外的处理和控制该校准过程。  During normal operation, the analog input is fed to the ADC 200 through the analog select switch 202, and the output of the ADC is corrected using the linearity corrector 100. The basic operation of the corrector has been described above in connection with Figures 2-4. Filters with this linearity corrector can be loaded by processor 204. Other processing can then be provided using the second processor 216, for example the corrected output can be processed like a direct output to the ADC. The embodiment shown in FIG. 6 shows acquisition memory 208 for calibration and other processing. In alternative embodiments, separate memory may be used for other processing. Similarly, the embodiment shown in Figure 6 shows a second processor 216, in other embodiments processor 204 can provide this additional processing and control the calibration process. the

如图7所示,校准线性校正器中的滤波器乘积内的一组滤波器,有四个基本步骤。对于第1阶以上的每个乘积阶,使用该乘积阶作为参数执行该步骤,例如第2阶或第3阶。步骤310采集和分析输入频率对的互调(IM)和谐波分量。步骤340使用步骤310的结果寻找该校正网络中的滤波器幅度和相位响应。步骤360使用在步骤340中找到的幅度和相位响应,根据所需的幅度和相位响应使用非线性相位滤波器设计算法来设计每个滤波器。步骤380通过设定该滤波器抽头来编程该线性校正器100内的滤波器以对ADC失真进行校正。  As shown in Figure 7, there are four basic steps to calibrating a bank of filters within a filter product in a linearity corrector. For each order of product above order 1, this step is performed using that order of product as a parameter, eg order 2 or order 3. Step 310 acquires and analyzes the intermodulation (IM) and harmonic components of the input frequency pair. Step 340 uses the results of step 310 to find the magnitude and phase response of the filters in the correction network. Step 360 uses the magnitude and phase responses found in step 340 to design each filter according to the desired magnitude and phase response using a nonlinear phase filter design algorithm. Step 380 programs the filter within the linearity corrector 100 to correct for ADC distortion by setting the filter taps. the

步骤310的基本信号采集和分析可以通过选择如图8中的步骤410所提供的基数据记录长度来完成。在步骤420中选择一组校准频率。步骤430生成两个基于额定校准频率的正弦输入,以及在步骤420中选择的校准指数。步骤440为每个校准中心频率指数计算一组谐波和互调频率。步骤450测试可能引起频率分量重叠的混叠。步骤460或者i)恰在所计算的谐波和互调频率执行一组离散傅里叶变换(DFT),或者ii)执行为完整的一组可能频率生成结果的快速傅里叶变换(FFT),然后,选择在该计算的谐波和互调频率上的输出结果。  The basic signal acquisition and analysis of step 310 can be accomplished by selecting the base data record length as provided in step 410 in FIG. 8 . In step 420 a set of calibration frequencies is selected. Step 430 generates two sinusoidal inputs based on the nominal calibration frequency, and the calibration index selected in step 420 . Step 440 calculates a set of harmonic and intermodulation frequencies for each calibration center frequency index. Step 450 tests for aliasing that may cause frequency components to overlap. Step 460 either i) performs a set of discrete Fourier transforms (DFT) at exactly the calculated harmonic and intermodulation frequencies, or ii) performs a fast Fourier transform (FFT) that produces results for the complete set of possible frequencies , then select the output at the calculated harmonic and intermodulation frequencies. the

在步骤410,选择用于DFT分析的基数据记录长度L。为了提高效率,在该校准方法的某些实施例中,将L选择为2的幂。对L的选择对应于基本分析频率F=fs/L,其中fs是采样率。然后将所有频率fm表示为基本分析频率F的谐波(整数倍)m,即fm=mF。角频率被表示为:  In step 410, a base data record length L is selected for DFT analysis. To improve efficiency, in some embodiments of the calibration method, L is chosen to be a power of two. The choice of L corresponds to the fundamental analysis frequency F=f s /L, where f s is the sampling rate. All frequencies f m are then expressed as harmonics (integer multiples) m of the fundamental analysis frequency F, ie f m =mF. The angular frequency is expressed as:

ωm=2πfm=2πmF=2πmfs/L            (方程7)  ω m = 2πf m = 2πmF = 2πmf s /L (Equation 7)

在步骤420,选择将用于随后步骤以设计滤波器响应的一组校准频率。这些频率被选择为F的谐波倍数,并且规则间隔在输入频率可以发生的整个尼奎斯特(Nyquist)频带中,但总是排除0(DC)的极限(extreme)和fs/2。  At step 420, a set of calibration frequencies is selected that will be used in subsequent steps to design the filter response. These frequencies are chosen as harmonic multiples of F and are regularly spaced throughout the Nyquist band where the input frequency can occur, but always excluding the extreme of 0 (DC) and f s /2.

在步骤430,对于具有额定校准频率ωc的每个校准指数c,以角频率ωc-1=ωc1和ωc+1=ωc1生成两个正弦输入,其对应于:  At step 430, for each calibration index c with nominal calibration frequency ω c , two sinusoidal inputs are generated at angular frequencies ω c-1 = ω c - ω 1 and ω c+1 = ω c + ω 1 corresponding to At:

xc(t)=pc-1sin(ωc-1(t+λc-1))+Qc+1sin(ωc+1(t+λc+1))        (方程8) x c (t) = p c-1 sin(ω c-1 (t+λ c-1 ))+Q c+1 sin(ω c+1 (t+λ c+1 )) (Equation 8)

其中λc是在频率指数c的延迟。在该校准方法的实施例中,幅度{Pc-1,Qc+1}是相似的以改善IM校准结果。任何微小差别可以在之后的校正阶段中去除。在该校准方法的实施例中,选择该校准频率以使得它们使用该ADC输入动态范围的大部分。然后,采集整数倍M组L个相邻的A/D输出样本。每个第M个样本被平均以获得低噪声y(t),t=0...L-1,其中L是上面步骤410中提供的该基数据记录长度。这种类型的简单平均是非常快的,允许对ML的大量值(可以是百万样本或更多)进行快速处理。L应当被选择成使得它不会太小或者使分析频率会分隔的太远。大的L的值可以生成比所需要的更多的校准频率数据,导致后面的算法运行更慢。L=210=1024的值已被成功地使用。  where λ c is the delay at frequency index c. In an embodiment of the calibration method, the magnitudes {P c-1 , Q c+1 } are similar to improve IM calibration results. Any small differences can be removed in a later correction stage. In an embodiment of the calibration method, the calibration frequencies are chosen such that they use a large part of the ADC input dynamic range. Then, an integer multiple of M groups of L adjacent A/D output samples is collected. Every Mth sample is averaged to obtain low noise y(t), t=0...L-1, where L is the base data record length provided in step 410 above. Simple averaging of this type is very fast, allowing fast processing of large numbers of values (could be millions of samples or more) for ML. L should be chosen such that it is not too small or that the analysis frequencies would be too far apart. Large values of L can generate more calibration frequency data than needed, causing subsequent algorithms to run more slowly. A value of L=2 10 =1024 has been successfully used.

在步骤440,对于每个校准中心频率指数c(其中0<c<L),产生一组谐波和互调频率。DC项被忽略,因为DC误差会由于许多其他原因而发生。例如,第二阶系统在{ωc-1c+1,2ωc-1,ωc-1c+1,2ωc+1,}具有IM和谐波失真频率,对应的指数:m={2,2c-2,2c,2c+2}。事实上,能够只使用和频(sum-frequency)项m={2c-2,2c,2c+2}来校准。仅使用频率的和项而不使用差项的优点在于,前者不是由任何低阶失真滤波器乘积生成。这包括可以称为第1阶(线性)“失真”系统的原始输入信号。  At step 440, for each calibration center frequency index c (where 0<c<L), a set of harmonic and intermodulation frequencies is generated. The DC term is ignored because DC errors can occur for many other reasons. For example, a second-order system with IM and harmonic distortion frequencies at {ω c-1 −ω c+1 , 2ω c-1 , ω c-1c+1 , 2ω c+1 ,}, corresponding to the exponent : m={2, 2c-2, 2c, 2c+2}. In fact, it is possible to calibrate using only the sum-frequency term m={2c-2, 2c, 2c+2}. The advantage of using only the sum term of frequencies and not the difference term is that the former is not generated by any low order distortion filter products. This includes the original input signal of what may be referred to as a 1st order (linear) "distorted" system.

应当注意,在采样的系统中,IM和谐波失真会包含混叠频率分量。因此,在步骤450,执行测试以处理混叠导致频率分量重叠的情况,因为该测量将与该失真模型不一致。对于给定c,生成一组可能的谐波和IM项(DC除外)。在一些实施例中,该组将包含除DC项之外的所有可能的谐波和IM项。对于来自步骤440的列表m中的指数mi的每个频率,由于采样理论不能区分频率间隔为L的混叠分量,所以它们相互卷绕如下:  It should be noted that in sampled systems, IM and harmonic distortion will contain aliased frequency components. Therefore, at step 450, a test is performed to handle the case where aliasing results in overlapping frequency components, since the measurement will not agree with the distortion model. For a given c, generate a set of possible harmonic and IM terms (except DC). In some embodiments, this set will contain all possible harmonic and IM terms except the DC term. For each frequency of indices mi from list m in step 440, since sampling theory cannot distinguish aliasing components with frequency interval L, they are convoluted with each other as follows:

w(mi)=mimodL         (方程9)  w(m i )=m i mod L (equation 9)

而且,在该卷绕间隔L内,混叠不能在w(mi)和L-w(mi)之间区分。该混叠的指数重新映射(aliased index remapping)是较低范围的解释(interpretation),由下式给出:  Also, within this wrapping interval L, aliasing cannot be distinguished between w(m i ) and Lw(m i ). This aliased index remapping is the lower range interpretation, given by:

alias(mi)=min(w(mi),L-w(mi))    (方程10)  alias(m i )=min(w(m i ), Lw(m i )) (equation 10)

其中min()是其输入值的最小值。因此0≤alias(m)<L/2。mi到alias(mi)的这种重新映射仅用于对于给定整数mi和L检测任何失真频率冲突。冲突检测大多很容易通过生成所有谐波和IM频率指数来实现,然后如上面在方程9和方程 10中所述重新映射每个频率指数,并且对得到的混叠频率指数值进行数字排序。然后,会发现具有相同重新映射频率指数值的相邻频率指数。如果发现有冲突,在该c值处不进行测量。如果L是2的幂,并且c是偶数,那么{c-1,c+1}总是互素的。从而,冲突仅发生在混叠频率。即使这样,通常冲突也是很少的。例如在第3阶系统中,冲突仅发生在c=L/4时。在这种情况下,互调分量位于2(L/4-1)+(L/4+1)=3L/4-1,所以其混叠频率是在L-(3L/4-1)=L/4+1,该频率也是输入频率。类似地,(L/4-1)+(2L/4+1)=3L/4+1,其混叠到上/4-1,也是输入频率。  where min() is the minimum value of its input value. Therefore 0≤alias(m)<L/2. This remapping of m i to alias(m i ) is only used to detect any distortion frequency collision for a given integer m i and L. Collision detection is mostly easy to implement by generating all harmonic and IM frequency indices, then remapping each frequency index as described above in Equation 9 and Equation 10, and numerically sorting the resulting aliased frequency index values. Then, adjacent frequency indices with the same remapped frequency index value are found. If a conflict is found, no measurement is performed at this value of c. If L is a power of 2, and c is even, then {c-1, c+1} is always relatively prime. Thus, collisions only occur at aliased frequencies. Even then, conflicts are usually rare. For example, in a 3rd order system, collisions only occur when c=L/4. In this case, the intermodulation product is located at 2(L/4-1)+(L/4+1)=3L/4-1, so its aliasing frequency is at L-(3L/4-1)= L/4+1, this frequency is also the input frequency. Similarly, (L/4-1)+(2L/4+1)=3L/4+1, which aliases onto /4-1, is also the input frequency.

在本校准方法的一个实施例中,在所选择的谐波和互调频率处执行一组L-样本的实数输入DFT,如步骤460所示。在每个频率m处的实数和虚数分量使用对于该平均实数样本序列的单个频率DFT来得到:  In one embodiment of the calibration method, a real input DFT of a set of L-samples is performed at the selected harmonic and intermodulation frequencies, as shown in step 460 . The real and imaginary components at each frequency m are obtained using a single frequency DFT on this averaged real sample sequence:

Xm=Re(ZmX m = Re(Z m )

Ym=Im(Zm)                 (方程11)  Y m = Im(Z m ) (Equation 11)

其中Re和Im是复输入的实部和虚部。方程11的形式是对于来自结合上述步骤410提供的方程7的正规化采样频率。在可选实施例中,可以使用快速傅里叶变换(FFT)代替多重DFT来获得在每个频率m处的实和虚分量。  where Re and Im are the real and imaginary parts of the complex input. The form of Equation 11 is for the normalized sampling frequency from Equation 7 provided in connection with step 410 above. In an alternative embodiment, a Fast Fourier Transform (FFT) may be used instead of multiple DFTs to obtain real and imaginary components at each frequency m. the

在该失真系统中,每个滤波器在这个阶段(stage)具有未知的幅度和相位响应。为了找到这些响应,提供用于该系统的失真的数学模型。基于提供的该模型,可以执行非线性优化。用于第N阶乘积的自调制模型将n个未知滤波器响应表示为每个乘积项的修改输入:  In this distorted system, each filter has an unknown magnitude and phase response at this stage. In order to find these responses, a mathematical model of the distortion for the system is provided. Based on this model provided, nonlinear optimization can be performed. The self-modulation model for the Nth order product represents n unknown filter responses as modified inputs for each product term:

     (方程12)  (Equation 12)

这种自调制模型可以以可选的一般形式重写为:  This self-modulation model can be rewritten in an optional general form as:

       (方程13)  (Equation 13)

其中:  in:

Figure S051D7332520060120D000114
                                  (方程14) 
Figure S051D7332520060120D000114
(Equation 14)

并且  and

Bi,c+1=Ai,c+1/Ai,c-1           (方程15) B i,c+1 = A i,c+1 /A i,c-1 (Equation 15)

假定有足够大的L,如果用于校准的两对频率C-1和C+1足够接近,则对于给定滤波器,在每个频率的延迟可以假定为近似相同,那么方程15可以简化为:  Assuming a sufficiently large L, if the two pairs of frequencies C-1 and C+1 used for calibration are close enough, then for a given filter, the delay at each frequency can be assumed to be approximately the same, then Equation 15 can be simplified to :

Figure S051D7332520060120D000121
             (方程16) 
Figure S051D7332520060120D000121
(Equation 16)

对于该第n阶失真系统,变量数等于2n+1。对于使用的每一对校准频率,到ADC的正弦波输入幅度都严密匹配。否则,该系统不能区分在两个不同频率处的它们的幅度之间的差别和每个滤波器的幅度响应中的差别。  For this nth order distortion system, the number of variables is equal to 2n+1. The sine wave input amplitudes to the ADC are closely matched for each pair of calibration frequencies used. Otherwise, the system cannot distinguish the difference between their magnitudes at two different frequencies and the difference in the magnitude response of each filter. the

如果在该两个不同的校准频率处通过每个滤波器的幅度响应是近似相同的,那么更简化的自调制模型可以提供如下:  If the magnitude response through each filter is approximately the same at these two different calibration frequencies, then a more simplified self-modulation model can be given as follows:

Figure S051D7332520060120D000122
              (方程17) 
Figure S051D7332520060120D000122
(Equation 17)

通过选择适合这些失真模型中的一个的ADC,如方程13、方程16或方程17所表示的,对于每个滤波通道在每个频率可以找到一组相位和幅度解。表示该失真模型的任何方程都可以被扩展以提供一组互调和谐波频率分量,其对应于上面在步骤440所找到的那些频率分量。该减少可以表示为在每个频率的余弦(实部)和正弦(虚部)项。一旦获得频率项的扩展和收集,连同在步骤460确定的那组DFT一起,那么就可以以符号表示的形式(symbolically)得到在这些表达式的实部和虚部与DFT结果之间的差的平方和,其可以从如上所述的DFT或FFT得到。这导致了对于第2阶失真的大的方程,以及对于每个更高阶的甚至更大的方程。  By choosing an ADC that fits one of these distortion models, as expressed in Equation 13, Equation 16, or Equation 17, a set of phase and magnitude solutions can be found for each filter channel at each frequency. Any equations representing this distortion model can be extended to provide a set of intermodulation and harmonic frequency components corresponding to those found at step 440 above. This reduction can be expressed as cosine (real part) and sine (imaginary part) terms at each frequency. Once the expansion and collection of frequency terms is obtained, along with the set of DFTs determined at step 460, the difference between the real and imaginary parts of these expressions and the DFT result can be obtained symbolically The sum of squares, which can be obtained from the DFT or FFT as described above. This results in a large equation for the 2nd order distortion, and an even larger equation for each higher order. the

因为相位和延迟λ通过角频率ω相关的,即通过:  because of phase And the delay λ is related to the angular frequency ω, that is, by:

             (方程18)  (Equation 18)

代入来自方程7的ωm,并且使用正规化频率(即fs=1),使得模型方程式中的任何方程13、方程16或方程17以频率指数的形式重写。例如,方程16可以重写为:  Substituting ω m from Equation 7, and using normalized frequencies (ie, f s =1), rewrites any Equation 13, Equation 16, or Equation 17 in the model equations in frequency exponential form. For example, Equation 16 can be rewritten as:

Figure S051D7332520060120D000125
         (方程19) 
Figure S051D7332520060120D000125
(Equation 19)

例如以阶数n=2分解成实部和虚部,我们扩展方程19并且收集项以获得在四个非DC互调和谐波频率指数的项:{2,2c,2c-2,2c+2}: For example decomposing into real and imaginary parts with order n=2, we extend Equation 19 and collect terms to obtain terms at four non-DC intermodulation and harmonic frequency indices: {2, 2c, 2c-2, 2c+2 }:

               (方程20)  (Equation 20)

Figure S051D7332520060120D000132
            (方程21) 
Figure S051D7332520060120D000132
(Equation 21)

     (方程22)  (Equation 22)

     (方程23)  (Equation 23)

其中该组系数{C,S}被确定为:  where the set of coefficients {C, S} is determined as:

对于方程20:  For equation 20:

Figure S051D7332520060120D000135
Figure S051D7332520060120D000135

对于方程21:  For equation 21:

Figure S051D7332520060120D000138
Figure S051D7332520060120D000138

对于方程22:  For equation 22:

对于方程23:  For equation 23:

Figure S051D7332520060120D0001312
Figure S051D7332520060120D0001312

现在,对这些系数和它们相对应的来自方程11的DFT或FFT分量之间的差的平方和进行估计:  Now, estimate the sum of squares of the differences between these coefficients and their corresponding DFT or FFT components from Equation 11:

                (方程24)  (Equation 24)

这里方程24可以表示该目标函数或者误差。对于第2阶的情况,要寻找的未知量可以用向量表示为:  Here Equation 24 may represent the objective function or error. For the second-order case, the unknown quantity to be searched can be expressed as a vector:

xc={Kc,B1,c+1,B2,c+11,c2,c}    (方程25) x c ={K c , B 1,c+1 , B 2,c+11,c2,c } (Equation 25)

一旦已经提供了该目标函数,就可以确定每个滤波器的幅度和相位响应。现在参照图9,示出了本校准方法的一个实施例。如步骤540中所示,首先将该目标函数最小化。在最小化该目标函数之后,对幅度执行解后校正(post-solution correction),如步骤560所示。该校正解现在被分解到为每一阶提供的滤波器之间,如步骤580所示。  Once this objective function has been provided, the magnitude and phase response of each filter can be determined. Referring now to FIG. 9, one embodiment of the present calibration method is shown. As shown in step 540, the objective function is first minimized. After minimizing the objective function, a post-solution correction is performed on the magnitude, as shown in step 560 . The corrected solution is now decomposed between the filters provided for each stage, as shown in step 580 . the

为了最小化该目标函数,如步骤540所示,将需要求解非线性方程的系统。可以使用一类基于牛顿(Newton-based)的算法来对每个预期的阶求解这些非线性方程和最小化该目标函数。可能的基于牛顿的算法包括修正牛顿(MN)、高斯一牛顿(GN)和准牛顿(Quasi-Newton)(QN)。在每个搜索迭代k,这些方法都估计该目标函数的数值梯度向量(gk)和该目标函数的Hessian(Sk)的数值逆,或者对于GN和QN方法是该目标函数的Hessian函数的逆的近似。该目标函数的梯度向量和该目标函数的Hessian的逆可以描述如下:  To minimize this objective function, as shown in step 540, will require solving a system of nonlinear equations. A class of Newton-based algorithms can be used to solve these nonlinear equations and minimize the objective function for each desired order. Possible Newton-based algorithms include Modified Newton (MN), Gauss-Newton (GN) and Quasi-Newton (QN). At each search iteration k, these methods estimate the numerical gradient vector (g k ) of the objective function and the numerical inverse of the Hessian (S k ) of the objective function, or for the GN and QN methods the Hessian of the objective function inverse approximation. The gradient vector of the objective function and the inverse of the Hessian of the objective function can be described as follows:

Figure S051D7332520060120D000141
    在x=xk                 (方程26) 
Figure S051D7332520060120D000141
at x = x k (equation 26)

  在x=xk                 (方程27)  At x = x k (equation 27)

通过估计该梯度向量和逆Hessian,能够获得可用于最小化该目标函数的搜索方向(dk),其中该搜索方向如下给出:  By estimating the gradient vector and the inverse Hessian, the search direction (d k ) that can be used to minimize the objective function can be obtained, where the search direction is given by:

dk=-Skgk                    (方程28)  d k = -S k g k (Equation 28)

该目标函数

Figure S051D7332520060120D000143
的梯度向量定义为这样一个向量,其第i个分量是该函数关于其第i个未知变量的偏导数。因此,它是这个阶段的符号结果而非数值。对于对应于方程16的具有5个未知量的第二阶情况,该目标函数由方程24提供:  The objective function
Figure S051D7332520060120D000143
The gradient vector of is defined as a vector whose ith component is the partial derivative of the function with respect to its ith unknown variable. Therefore, it is a symbolic result of this stage rather than a numerical value. For the second order case with 5 unknowns corresponding to Equation 16, this objective function is given by Equation 24:

Figure S051D7332520060120D000144
Figure S051D7332520060120D000144

Hessian矩阵的第(i,j)个元素是该目标函数对于其第i个和第j个变量的偏导数。再次,对于第2阶情况,该Hessian矩阵如下给出:  The (i, j)th element of the Hessian matrix is the partial derivative of the objective function with respect to its i-th and j-th variables. Again, for the 2nd order case, the Hessian matrix is given as:

Figure S051D7332520060120D000151
Figure S051D7332520060120D000151

因此该矩阵元素是该未知变量x的项。该偏导运算符是可交换的,所以Hessian矩阵总是平方对称的(square-symmetric)。  The matrix elements are therefore entries for the unknown variable x. The partial derivative operator is commutative, so the Hessian matrix is always square-symmetric. the

对于该目标函数可以找到相应的梯度和Hessian矩阵。虽然求解这种复杂表达式的导数是非常繁复的,但是可以通过使用符号数学软件工具例如在Mathematica中的符号导数函数来执行计算机化符号计算。可选地,可以使用众所周知的近似来数值地求解任何函数f(x)的导数f′(x):  The corresponding gradient and Hessian matrix can be found for this objective function. Although solving the derivatives of such complex expressions is very tedious, computerized symbolic computations can be performed by using symbolic mathematics software tools such as the symbolic derivative function in Mathematica. Alternatively, the derivative f′(x) of any function f(x) can be solved numerically using well-known approximations:

                         (方程29)  (Equation 29)

对于适当小的值Δ,假定该计算精度可用。可以使用符号或者数值微分。符号微分可以通过符号数学软件来提供,通过这种软件提供的这种处理对处理器204使用通用处理器。应当注意,如果已经得到了符号微分,在本校准方法的一些实施例中,可以使用较低级语言例如C语言将这些符号结果编码为函数,以便改善在处理器204中的这种操作的性能。在可选实施例中,可以由处理器使用数值微分代替提供该符号解的编码实施。  For suitably small values of Δ, this computational precision is assumed to be available. Symbolic or numerical differentiation can be used. Symbolic differentiation may be provided by symbolic mathematics software, and such processing provided by such software uses a general-purpose processor for processor 204 . It should be noted that if symbolic differentiation has been obtained, in some embodiments of the present calibration method these symbolic results can be encoded as functions using a lower level language such as C to improve the performance of this operation in processor 204 . In an alternative embodiment, numerical differentiation may be used by the processor instead of an encoded implementation providing the symbolic solution. the

如上所述,可以通过使用基于牛顿的算法直接或叠代求解逆Hessian。例如,在本校准方法的一个实施例中,使用准牛顿算法叠代确定该Hessian矩阵的逆的近似值。有多个QN叠代的子范畴可以使用。例如可以使用BFGS(Broyden,Fletcher,Goldfarb,Shanno)叠代公式。在本校准方法的一个实施例中,该BFGS叠代公式与弗莱彻线搜索(Fletcher’s Line Search)算法一起使用。 该逆Hessian Sk+1的第(k+1)次BFGS叠代如下给出:  As mentioned above, the inverse Hessian can be solved directly or iteratively by using Newton-based algorithms. For example, in one embodiment of the present calibration method, an approximation of the inverse of the Hessian matrix is determined iteratively using a quasi-Newton algorithm. There are multiple subcategories of QN iterations that can be used. For example, the BFGS (Broyden, Fletcher, Goldfarb, Shanno) iteration formula can be used. In one embodiment of the calibration method, the BFGS iterative formula is used with the Fletcher's Line Search algorithm. The (k+1)th BFGS iteration of the inverse Hessian S k+1 is given by:

           (方程30)  (Equation 30)

其中列向量pk、标量qk和方矩阵rk如下给出:  where the column vector p k , the scalar q k and the square matrix r k are given by:

pk=Skγk p k =S k γ k

                        (方程31)  (Equation 31)

Sk(方矩阵)是该逆Hessian的第k次近似值,而S0=I为单位矩阵。应当注意,上标T是转置,例如:是δk的转置。并且列向量:  S k (square matrix) is the kth approximation of the inverse Hessian, and S 0 =I is the identity matrix. It should be noted that the superscript T is transpose, eg: is the transpose of δ k . and a column vector:

γk=gk+1-gk               (方程32)  γ k =g k+1 -g k (Equation 32)

其中gk是较早从(方程26)中获得的梯度向量。对于下一个叠代的该新的解向量估计xk+1由应用到该前一个xk的校正列向量δk给出:  where g k is the gradient vector obtained earlier from (Equation 26). The new solution vector estimate xk +1 for the next iteration is given by the correction column vector δk applied to the previous xk :

xk+1=xkk           (方程33)  x k+1 = x kk (Equation 33)

为了寻找每个叠代的未知的δk,使用沿着搜索方向dk的约束搜索。一旦使用方程33找到xk并且使用方程28和方程30找到dk,然后,就找到了非负标量αk,其最小化:  To find the unknown δk for each iteration, a constrained search along the search direction dk is used. Once x k is found using Equation 33 and d k is found using Equations 28 and 30, then, a non-negative scalar α k is found that minimizes:

e2(xk+1)=e2(xkk)=e2(xkkdk)    (方程34)  e 2 (x k+1 )=e 2 (x kk )=e 2 (x kk d k ) (Equation 34)

这是αk中的一维优化问题,而不论该原始问题的维数如何。因而,对这种特定类型方程的求解已知为线搜索。  This is a one-dimensional optimization problem in α k regardless of the dimensionality of the original problem. Thus, the solution of this particular type of equation is known as a line search.

当前的解可估计向量xk,且其相应的搜索方向dk被给定作为弗莱彻线搜索算法的输入,以给出标量值αk。于是,对于方程33中的对xk的列向量校正如下给出:  The current solution may estimate a vector x k , and its corresponding search direction d k is given as input to the Fletcher line search algorithm to give a scalar value α k . Then, the column vector correction for x k in Equation 33 is given by:

δk=xk+1-xk=αkdk    (方程35)  δ k =x k+1 -x kk d k (Equation 35)

众所周知,在一般情况下,寻找目标函数的全局最小值是一个困难问题。所找到的最小值总是依赖于该目标函数,但是也可以依赖于该初始条件x0°如果该失真模型能够相当好地符合,那么通常收敛会迅速和可靠。然而,如果该真实的失真机制包括多个失真乘积或者其他一些不遵循该失真模型的机制,则该解会发散。在这种情况下,向一个解前进,并且该误差函数方程24在每次叠代中减少,但是向量x中的未知量之一按指数规律向无穷发散。对BFGS叠代数量的限制可以可靠地检测这种问题。然而,到达这种限制的过程也减慢了该校准算法。  It is well known that finding the global minimum of the objective function is a difficult problem in general. The minimum found always depends on the objective function, but can also depend on the initial condition x 0 ° If the distortion model fits reasonably well, the convergence is usually fast and reliable. However, if the true distortion mechanism includes multiple distortion products or some other mechanism that does not follow the distortion model, the solution will diverge. In this case, a solution is advanced, and the error function equation 24 decreases in each iteration, but one of the unknowns in the vector x diverges exponentially towards infinity. A limit on the number of BFGS iterations can reliably detect this kind of problem. However, reaching this limit also slows down the calibration algorithm.

如果在噪声减少平均后,看到发散,那么可以设置发散失败标记以指示对 于进一步诊断的需要,或者该ADC的失败。  If, after noise reduction averaging, divergence is seen, a divergence failure flag can be set to indicate the need for further diagnostics, or failure of the ADC. the

然而,一旦逼进最小解,则算法收敛是二次的,所以能迅速收敛到可重复的结果。这种特性可以用于探索方程16的模型的解空间。如果一个解收敛到在先找到的解,则可以作为重复解而拒绝。该过程会继续,直到已经获得不能再找到最小值的统计上符合要求的判断。  However, once the minimum solution is approached, the algorithm converges quadratically, so it converges quickly to repeatable results. This property can be used to explore the solution space of the model of Equation 16. A solution can be rejected as a duplicate if it converges to a previously found solution. This process continues until a statistically satisfactory decision has been obtained that no further minimum can be found. the

在本校准方法的一些实施例中,在具有π的邻近整数倍的角度处可能有其他邻近解。这些重复解由于微不足道地相关或“无兴趣”而被辨别并被排除。  In some embodiments of the present calibration method, there may be other adjacent solutions at angles having adjacent integer multiples of π. These duplicate solutions were identified and rejected as trivially relevant or "uninteresting". the

找到解的一个方法是在方程19中以B的随机值开始x,使用:  One way to find the solution is to start x with a random value of B in Equation 19, using:

B=eu(Random-1/2)               (方程36)  B = e u(Random-1/2) (Equation 36)

Random是从0到1的随机实数值。u=0.1的值对于实数ADC数据可以有很好的效果。每个角

Figure S051D7332520060120D000171
可以在以下范围中随机产生:  Random is a random real value from 0 to 1. A value of u=0.1 can have good results for real ADC data. each corner
Figure S051D7332520060120D000171
Can be randomly generated in the following ranges:

Figure S051D7332520060120D000172
                  (方程37) 
Figure S051D7332520060120D000172
(Equation 37)

然后可以使用方程18在已知频率将角转变为方程19中的延迟。  The angle can then be converted to a delay in Equation 19 at a known frequency using Equation 18. the

在另一实施例中,通过将用作校准指数c的函数的随机角的初始范围限制到在先前校准中的起作用的范围来寻找已知ADC设计的解。对初始范围的这种限制会加速该解的搜索。  In another embodiment, a solution for a known ADC design is found by restricting the initial range of random angles used as a function of the calibration index c to the range that worked in previous calibrations. This restriction on the initial range speeds up the search for the solution. the

即使该开始值至少被方程37约束,该最终值也可以存在于这些范围之外而进入最接近的相邻重复解中。这是因为该开始点可以存在于在该重复最小值之间的重复的“峰”的另一侧。然而,由于在该间隔π的重复的函数“形状(landscapes)”的相似性,即使更远也不会找到重复解。在本校准方法的一个实施例中,找到了最近的相邻解并且排除了重复解。  Even if the starting value is constrained by at least Equation 37, the final value may exist outside these ranges into the closest adjacent iterative solution. This is because the start point may exist on the other side of the repeated "peak" between the repeated minima. However, due to the similarity of the repeated function "landscapes" at the interval π, no repeated solution will be found even further. In one embodiment of the present calibration method, nearest neighbor solutions are found and duplicate solutions are excluded. the

对于每个校准频率,一旦找到第一解angle,就可以很容易地找到中心解(即角最接近0)。在本校准方法的一个实施例中,所找到的角直接被验证为中心解(在±π/2内)。在可选实施例中,使用multiple=floor(angle/π+0.5)来寻找距该中心解区域最接近的π的整数倍,然后将该π的倍数从该第一解角(solutionangle)中减去以使该角进入该中心区域中。在一些应用中,接近±π/2的解可以随着在另外具有校准频率的角度平滑变化中的在+π/2或-π/2之间的噪声波动。这些波动可以通过在之后的处理中查找角的连续性而得到校正。然后,该BFGS算法的第二次运行可以通过使用被替换的第一解作为好的开始点而迅速找到更准确的中心解。 For each calibration frequency, once the first solution angle is found, the central solution (i.e. the angle closest to 0) can be easily found. In one embodiment of the present calibration method, the found angles are directly verified as central solutions (within ±π/2). In an alternative embodiment, multiple=floor(angle/π+0.5) is used to find the closest integer multiple of π to the central solution region, and then the multiple of π is subtracted from the first solution angle (solution angle) Go to bring the corner into the center area. In some applications, a solution close to ±π/2 may fluctuate with noise between +π/2 or -π/2 in an otherwise smooth change in angle with a calibration frequency. These fluctuations can be corrected by looking for angular continuity in later processing. Then, a second run of the BFGS algorithm can quickly find a more accurate central solution by using the substituted first solution as a good starting point.

从该中心解,可以系统地找到距离该中心解最近的相邻解。如上面寻找该中心解的过程,可以通过将{-π,0,π}的所有组合加到每个角并且使用作为结果的向量作为BFGS解搜索的开始点来找到该重复解。再次,因为每个开始点非常接近该正确值,BFGS算法非常迅速地收敛。对于第2阶搜索有32-1=8个相邻解,对于第3阶搜索有33-1=26个相邻解。  From this central solution, the nearest neighboring solutions to this central solution can be found systematically. As in the process of finding the central solution above, the repeated solution can be found by adding all combinations of {-π, 0, π} to each corner and using the resulting vector as the starting point for the BFGS solution search. Again, because each starting point is very close to the correct value, the BFGS algorithm converges very quickly. There are 3 2 −1=8 adjacent solutions for the 2nd order search and 3 3 −1=26 adjacent solutions for the 3rd order search.

找到这些解之后,可以使用在其他随机开始位置的搜索来寻找任何更多的解,如果它们存在的话。如果一个解与先前找到的解中的一个匹配,则拒绝它。如前面所述,通过由具有符号梯度的BFGS算法找到的解的高重复性而使得验证重复(duplicate)的过程变得更简单。  After finding these solutions, a search at other random starting positions can be used to find any more solutions, if they exist. If a solution matches one of the previously found solutions, it is rejected. As mentioned earlier, the process of verifying duplicates is made easier by the high repeatability of the solutions found by the BFGS algorithm with signed gradients. the

如果一个新解与迄今所找到的任何一个都不匹配,则可以找到其中心解,并且使用与前述相同的方法找到其所有相邻解。在本校准方法的一个实施例中,富有成效的搜索结果重设超时计数器(tmeout counter),而寻找新解的失败则减少该超时计数器。如果该超时(timeout)到达零,则停止对其他解的搜索。选择根据方程24给出最好的误差测量的中心解作为对于该校准频率指数的最终解。  If a new solution does not match any found so far, its central solution can be found, and all its neighbors can be found using the same method as before. In one embodiment of the calibration method, fruitful search results reset a timeout counter (tmeout counter), while failures to find new solutions decrement the timeout counter. If this timeout reaches zero, the search for other solutions stops. The central solution that gives the best error measure according to Equation 24 is chosen as the final solution for the calibrated frequency index. the

在本校准方法的一个实施例中,如果已经在先前的校准频率指数cprev找到一个解,则可以使用它作为在c的下一次搜索的开始点。如果它不能收敛,则使用前述的慢的随机搜索方法。  In one embodiment of the present calibration method, if a solution has been found at the previous calibration frequency index c prev , it can be used as the starting point for the next search at c. If it fails to converge, the aforementioned slow random search method is used.

如果对于特定的c没有找到解,可以使用在cnext的解作为开始点进行第二次扫描(pass)。如果仍然没有找到解,那么可以使用相邻值之间的修补(patching)或内插。如果对太多的校准值指数都没有能找到解,则该ADC是有故障的,可以设定一个故障标记。  If no solution is found for a particular c, a second pass can be made using the solution at c next as a starting point. If a solution is still not found, then patching or interpolation between adjacent values can be used. If no solution can be found for too many calibration value indices, then the ADC is faulty and a fault flag can be set.

如果对于所有校准频率已经找到可以接受的一组懈,则进入该自调制系统的乘积的每个通道的幅度和相位响应的特征在于该组选定的离散的校准频率。利用这些频率的均匀分布,对于每个通道的响应可以由如图2-4中的FIR滤波器所表示。在本校准方法的一个实施例中,现在对每个滤波器的系数进行叠代寻找。  If an acceptable set of calibration frequencies has been found for all calibration frequencies, then the magnitude and phase response of each channel into the product of the self-modulation system is characterized by the set of selected discrete calibration frequencies. With a uniform distribution of these frequencies, the response for each channel can be represented by an FIR filter as in Figures 2-4. In one embodiment of the calibration method, the coefficients of each filter are now iteratively found. the

在本校准方法的另一实施例中,对来自方程25的该组向量xc在将它们传送到该滤波器设计之前进行校正,如步骤560所示。在本校准方法的实施例中,该校准输入的幅度在合理的校准范围上将不会显著影响该滤波器响应。从方程14可以看出,这种依赖性通过用除Kc而可以被消除,其中n是该乘积阶指数。而且,在一些实施例中,在方程8的两个校准正弦输入的幅度中的任何差 别还应当对该滤波器响应具有可以忽略的影响。在这种情况下,不仅该失真滤波器的相对响应,而且该校准正弦输入的相对幅度都会影响该测量结果。因此,在这些实施例中,使用相对幅度Pc-1和Qc+1来进行校正。该比率:  In another embodiment of the calibration method, the set of vectors xc from Equation 25 are calibrated before they are passed to the filter design, as shown in step 560 . In an embodiment of the calibration method, the magnitude of the calibration input will not significantly affect the filter response over a reasonable calibration range. As can be seen from Equation 14, this dependence is achieved by using can be eliminated by dividing Kc , where n is the order index of the product. Also, in some embodiments, any difference in the amplitudes of the two calibration sinusoidal inputs of Equation 8 should also have negligible effect on the filter response. In this case, not only the relative response of the distortion filter, but also the relative magnitude of the calibration sinusoidal input affects the measurement. Therefore, in these embodiments, the relative magnitudes P c-1 and Q c+1 are used for correction. The ratio:

Rc=Qc+1/Pc-1             (方程38)  R c =Q c+1 /P c-1 (Equation 38)

给出了在x中B参数被高估的量。因此对方程25中的x的该参数针对第n阶校准进行校正以给出新向量Xc如:  gives the amount by which the B parameter is overestimated in x. This parameter of x in equation 25 is therefore corrected for the nth order calibration to give a new vector X as :

Figure S051D7332520060120D000191
            (方程39) 
Figure S051D7332520060120D000191
(Equation 39)

在任何校准频率,滤波器乘积系统的组合幅度响应是每个滤波器的幅度响应的函数。因此,我们可以使得一个滤波器的系数变大两倍,而另一个缩小两倍,而具有相同的结果。系统幅度响应的变化在校准频率之间可以是重要的。我们可以通过使得乘积中的每个滤波器对于第n阶失真校正系统具有相同的来自方程39中第一项的第1/n次方根响应,从而在滤波器乘积系统中的所有滤波器中平均分散跟踪幅度响应变化的负荷,以使:  At any calibration frequency, the combined magnitude response of the filter product system is a function of the magnitude response of each filter. Thus, we can make the coefficients of one filter twice as large and the other twice smaller, with the same result. Variations in the magnitude response of the system can be significant between calibration frequencies. We can achieve this across all filters in the filter product system by making each filter in the product have the same 1/nth root response from the first term in Equation 39 for the nth order distortion corrected system The average dispersion tracks the magnitude response to varying loads such that:

Figure S051D7332520060120D000192
                    (方程40) 
Figure S051D7332520060120D000192
(equation 40)

对于第n阶失真系统,在频率指数c的每个向量Xc中有n对幅度和频率响应。对n个滤波器中的一个任意指定一对幅度和相位响应,对作为频率的函数的每个滤波器可能会产生非平滑幅度响应、相位响应,或者两者。非平滑响应可以产生不能对选择的滤波器长度很好地跟踪预期响应的滤波器设计。因而,该幅度响应和相位响应被分配到每一阶可用的滤波器之间,如步骤580所示。因为一组足够密集的校准频率通常会导致对于相邻校准指数的延迟响应之间的高的相关度,所以在本校准方法的一个实施例中,通过以该校准循环周期(1/fc-1)的一半为模,测试相对于在频率指数cprev处的前一组的新组可能的置换,来获得在该新组延迟和先前一组延迟之间的更好的配合。在奇数个滑移(slips)的情况下,将对应于半个循环的延迟应用到该滤波器之一。在本校准方法的实施例中,例如采用方程16所述的模型的实施例,每个相位值具有相应的幅度,所以重新排列相位也重新排列相应的幅度。如果两个相位交叉,它们可以被分组为对一个滤波器的最小相位值和对另一滤波器的最大相位值。在每个相位图上导致的绞缠(kink)不会像不连续性一样对所得到的滤波器质量不利,而是产生可行的滤波器设计,如果提供足够的滤波器抽头的话。  For an nth order distorted system, there are n pairs of amplitude and frequency responses in each vector Xc of frequency index c. Arbitrarily specifying a pair of magnitude and phase responses to one of the n filters may produce a non-smooth magnitude response, phase response, or both for each filter as a function of frequency. A non-smooth response can result in a filter design that does not track the expected response well for the chosen filter length. Thus, the magnitude and phase responses are distributed among the available filters at each stage, as shown in step 580 . Because a sufficiently dense set of calibration frequencies usually results in a high degree of correlation between the delayed responses to adjacent calibration indices, in one embodiment of the calibration method, by using the calibration cycle period (1/f c- Modulo half of 1 ), test possible permutations of the new set relative to the previous set at frequency index c prev to obtain a better fit between this new set of delays and the previous set of delays. In case of an odd number of slips, a delay corresponding to half a cycle is applied to one of the filters. In embodiments of the calibration method, such as those employing the model described in Equation 16, each phase value has a corresponding magnitude, so rearranging the phases also rearranges the corresponding magnitudes. If two phases cross, they can be grouped into the minimum phase value for one filter and the maximum phase value for the other filter. The resulting kink on each phase map is not as detrimental to the resulting filter quality as a discontinuity, but results in a feasible filter design, provided enough filter taps are provided.

通过前面的校准步骤,对于每个滤波器路径都获得一组适当分组的幅度和 相位响应。图6中的滤波器设计步骤360使用在步骤340计算的该幅度和相位响应设计每个滤波器,以给出对该计算的响应的近似。在射频(RF)应用的情况,使用该ADC的上Nyquist频带的中间部分,而不对该频带中的外部频率区域进行校准。这意味着该外部频率是不受约束的。如图10所示,在本校准方法的实施例中,使用叠代过程来完成该滤波器设计和寻找该滤波器抽头。在可选实施例中,可以使用简单的逆FFT。  Through the previous calibration steps, an appropriately grouped set of magnitude and phase responses is obtained for each filter path. The filter design step 360 in FIG. 6 designs each filter using the magnitude and phase responses calculated in step 340 to give an approximation of the calculated response. In the case of radio frequency (RF) applications, the middle part of the upper Nyquist band of the ADC is used without calibration for the outer frequency regions in the band. This means that the external frequency is not constrained. As shown in Figure 10, in an embodiment of the calibration method, an iterative process is used to accomplish the filter design and find the filter taps. In an alternative embodiment, a simple inverse FFT can be used. the

如步骤610所示,对每个通道选择一个滤波器长度。在本校准方法的一个实施例中,对于所有通道使用相同的滤波器长度。在可选实施例中,对于部分或所有通道使用不同的滤波器长度。在本可选实施例中,可以需要额外的延迟以补偿该不同的滤波器长度。该滤波器长度可以至少部分依赖于该预期的性能和被校准的ADC。以示例的方式,使用了全部63抽头的滤波器长度或者全部127抽头的滤波器长度。  As shown in step 610, a filter length is selected for each channel. In one embodiment of the calibration method, the same filter length is used for all channels. In alternative embodiments, different filter lengths are used for some or all channels. In this alternative embodiment, an additional delay may be required to compensate for this different filter length. The filter length can depend at least in part on the expected performance and the ADC being calibrated. By way of example, a full filter length of 63 taps or a full filter length of 127 taps are used. the

在步骤620,选择FFT长度并且将该幅度和相位响应转换为复直角坐标的滤波器频率响应向量。该FFT长度应当比在步骤610选择的滤波器长度要长。例如,在本校准方法的实施例中,选择512个样本的实数FFT长度。因为该FFT比滤波器长度长,所以这里将对应于滤波器抽头的频率之外的值初始化为零。  At step 620, an FFT length is selected and the magnitude and phase responses are converted to a filter frequency response vector in complex Cartesian coordinates. The FFT length should be longer than the filter length selected in step 610 . For example, in an embodiment of the present calibration method, a real FFT length of 512 samples is chosen. Because the FFT is longer than the filter length, values other than frequencies corresponding to filter taps are initialized to zero here. the

在步骤630,执行该滤波器频率响应向量的逆FFT以获得一组实数滤波器抽头,但是还有扩展到该FFT长度例如512的抽头。在时域中,超出该选择的滤波器长度的抽头被强制为零。  At step 630, an inverse FFT of the filter frequency response vector is performed to obtain a set of real filter taps, but also taps extended to the FFT length, eg 512. In the time domain, taps beyond this chosen filter length are forced to zero. the

在步骤640,执行前向FFT以回到频域。该频率响应向量的一些区域应当是不受约束的。在所关心的频率的FFT槽(bins)被重写回对于该预期幅度和频率响应的原始值,使得该不受约束的频率槽(frequency bins)不变。  At step 640, a forward FFT is performed to go back to the frequency domain. Some regions of the frequency response vector should be unconstrained. The FFT bins at the frequency of interest are rewritten back to the original values for the expected magnitude and frequency response, leaving the unconstrained frequency bins unchanged. the

重复步骤630和640以叠代收敛到预期解。一旦在步骤630提供的该滤波器抽头已经从先前的叠代中变得稳定,就找到了该滤波器抽头。  Steps 630 and 640 are repeated to iteratively converge to the desired solution. Once the filter tap provided at step 630 has become stable from the previous iteration, the filter tap is found. the

一旦从步骤630获得该滤波器抽头,就可以如图3中的步骤380所提供的那样对硬件编程。该编程滤波器乘积系统现在能够对ADC谐波和互调失真进行校正。  Once the filter taps are obtained from step 630, the hardware can be programmed as provided at step 380 in FIG. The programmed filter product system is now capable of correcting for ADC harmonic and intermodulation distortion. the

本领域普通技术人员将会清楚,可以对本发明的上述实施例细节进行许多改变,而不脱离其基本原则。因此,本发明的范围应当由所附的权利要求来确定。 It will be apparent to those of ordinary skill in the art that many changes may be made to the details of the above-described embodiments of the present invention without departing from the basic principles thereof. Accordingly, the scope of the invention should be determined by the appended claims.

                            Slavin.txt  Slavin.txt

Mathematica code for ADC Correction Algorithm.  Mathematica code for ADC Correction Algorithm. 

(*Copyright 2005 Tektronix Inc.*)  (*Copyright 2005 Tektronix Inc.*)

(*by Keith Slavin*)  (*by Keith Slavin*)

(*COPYRIGHT NOTIFICATION  (*COPYRIGHT NOTIFICATION

*Pursuant to 37 C.F.R.1.71(e),applicant notes that a portion of this disclosure  *Pursuant to 37 C.F.R.1.71(e), applicant notes that a portion of this disclosure

contains material that  contains material that

*is subject to and for which is claimed copyright protection,such as,but not  *is subject to and for which is claimed copyright protection, such as, but not

limited to,source code listings,  limited to, source code listings,

*screen shots,user interfaces,or user instructions,or any other aspects of this  *screen shots, user interfaces, or user instructions, or any other aspects of this

submission for which copyright  submission for which copyright

*protection is or may be available in any jurisdiction.The copyright owner has no  *protection is or may be available in any jurisdiction. The copyright owner has no

objection to the facsimile  objection to the facsimile

*reproduction by anyone of the patent document or patent disclosure,as it appears  *reproduction by anyone of the patent document or patent disclosure, as it appears

in the Patent and Trademark office  in the Patent and Trademark office

*patent file or records.All other rights are reserved,and all other  *patent file or records. All other rights are reserved, and all other

reproduction,distribution,  reproduction, distribution,

*creation of derivative works based on the contents,public display,and public  *creation of derivative works based on the contents, public display, and public

performance of the application  performance of the application

*or any part thereof are prohibited by applicable copyright law.  *or any part thereof are prohibited by applicable copyright law. 

*)  *)

BeginPackage[″correction`″,″Global`″]  BeginPackage["correction`", "Global`"]

(*frequency Indexing:i1=i-1,i2=i+1*)  (*frequency Indexing: i1=i-1, i2=i+1*)

(*  (*

 *design filters to correct ADC output.lowF,hiF are normalized  *design filters to correct ADC output.lowF,hiF are normalized

 *frequencies from 0 to 0.5(of fs).′data′is a 2-Darray of acquired  *frequencies from 0 to 0.5(of fs).'data'is a 2-Darray of acquired

 *ADC data in/login/keith/adc_orrection/xcal_data6/summary.To load,  *ADC data in/login/keith/adc_correction/xcal_data6/summary.To load,

 *type:<<Z:adc_correction\xcal_data6\summary;The result is in″data″.  *type:<<Z:adc_correction\xcal_data6\summary; The result is in "data". 

 *Type:ProcessData[data,0.1,0.4,127,10^-12]to get the filter  *Type: ProcessData[data, 0.1, 0.4, 127, 10^-12] to get the filter

 *coefficients in the form:  *coefficients in the form: 

 *{{2nd_orde_f1_list,2nd_order_f2_list},  *{{2nd_orde_f1_list, 2nd_order_f2_list}, 

 *{3rd_order_f1_list,3rd_orde_f2_list,3rd_order_f3_list}}  *{3rd_order_f1_list, 3rd_orde_f2_list, 3rd_order_f3_list}} 

 *)  *)

ProcessData[caldata_,calFreqLo_,calFreqHi_,correctFilterLen_,error_]:=  ProcessData[caldata_, calFreqLo_, calFreqHi_, correctFilterLen_, error_]: =

  Module[  Module[

   {order,responses2,correctionFilters2,responses3,correctionFilters3,  {order, responses2, correctionFilters2, responses3, correctionFilters3,

    correctionFilters},  correctionFilters},

    order=2;  order=2;

   Print[″Generate′rsponses2′:″];  Print[″Generate′rsponses2′:″];

   responses2=ProcessCalData[ca]data,order,calFreqLo,calFreqHi,error];  responses2=ProcessCalData[ca]data, order, calFreqLo, calFreqHi, error];

   (*design the correction filters from the cal responses*)  (*design the correction filters from the cal responses*)

   print[″Generate′correctionFilters2':″];  print["Generate'correctionFilters2':"];

   correctionFilters2=DesignFilters[responses2,correctFilterLen];  correctionFilters2 = DesignFilters[responses2, correctFilterLen];

   order=3;  order=3;

   Print[″Generate′responses3′:″];  Print[″Generate′responses3′:″];

   responses3=ProcessCalData[caldata,order,calFreqLo,calFreqHi,error];  responses3 = ProcessCalData[caldata, order, calFreqLo, calFreqHi, error];

   Print[″Generate′correctionFilters3′:″];  Print[″Generate′correctionFilters3′:″];

   correctionFilters3=DesignFilters[responses3,correctFilterLen];  correctionFilters3 = DesignFilters[responses3, correctFilterLen];

   Return[{correctionFilters2,correctionFilters3}];  Return[{correctionFilters2, correctionFilters3}];

]

                                       Page1 Page1

                            Slavin.txt  Slavin.txt

(*  (*

 * Run a calibration on randomly generated distortion filters,and then correct  * Run a calibration on randomly generated distortion filters, and then correct

 * the same distortion on a multi-sine input signal.  * the same distortion on a multi-sine input signal. 

 *  (*Note:0.2...0.3 range puts 3rd order IM in 0.1...0.4fs  * (*Note: 0.2...0.3 range puts 3rd order IM in 0.1...0.4fs

 *     and 2nd order IM from 0...0.1 and from 0.4...0.5fs.*)  * and 2nd order IM from 0...0.1 and from 0.4...0.5fs.*) 

 *  testFreqLo=0.2;  * testFreqLo = 0.2;

 *  testFreqHi=0.3;  * testFreqHi=0.3;

 *  testFreqStep=0.004;    (*step in fs units from testFreqLo to testFreqHi*)  * testFreqStep=0.004; (*step in fs units from testFreqLo to testFreqHi*)

 *  calFreqLo=0.1;(*low calibration range in fs units*)  * calFreqLo=0.1; (*low calibration range in fs units*)

 *  calFreqHi=0.4; (*high calibration rage in fs units*)  * calFreqHi=0.4; (*high calibration rage in fs units*)

 *  distortFilterLen=63;(*odd length of all distorting filters*)  * distortFilterLen=63; (*odd length of all distorting filters*)

 *  spread=4.0;(*spread(samples)of random distorting filters*)  * spread=4.0; (*spread(samples) of random distorting filters*)

 *  analysisLen=1024;(*samples in DFT analysis of cal frequencies*)  * analysisLen=1024; (*samples in DFT analysis of cal frequencies*)

 *  freqPairs=128;(*frequency pairs in cal(must divide analysisLen)*)  * freqPairs=128; (*frequency pairs in cal(must divide analysisLen)*)

 *  correctFilterLen=63;(*correction filter lengths(must be odd)*)  * correctFilterLen=63; (*correction filter lengths(must be odd)*)

 *  testLen=32768;(*samples used in test signal analysis*)  * testLen=32768; (*samples used in test signal analysis*)

 *  *

 *  these three parameters are in LSB units.They make  * these three parameters are in LSB units.They make

 *  noise+distortion+original tones with similar amplitudes to the  * noise+distortion+original tones with similar amplitudes to the

 *  AD6645 ADC:  * AD6645 ADC:

 *  *

 *  distortionAmpl=0.04;  * distortionAmpl = 0.04;

 *  tonePairAmpl=15000.0;  * tonePairAmpl = 15000.0;

 *  noiseAmpl=2.0;  * noiseAmpl = 2.0;

 *)  *)

Demo[]:=  Demo[]:=

  Module[  Module[

    {}  {} 

    MainTest[0.2,0.3,0.004,0.1,0.4,63,4.0,1024,128,63,32768,  MainTest[0.2, 0.3, 0.004, 0.1, 0.4, 63, 4.0, 1024, 128, 63, 32768,

             0.04,15000.0,0.01];  0.04, 15000.0, 0.01];

    ]  ]

MainTest[testFreqLo_,testFreqHi_,testFreqStep_,calFreqLo_,calFreqHi_,  MainTest[testFreqLo_, testFreqHi_, testFreqStep_, calFreqLo_, calFreqHi_,

         distortFilterLen_,spread_,analysisLen_,freqPairs_,  distortionFilterLen_, spread_, analysisLen_, freqPairs_,

         correctFilterLen_,testLen_,  correctFilterLen_, testLen_,

         distortionAmpl_,tonePairAmpl_,noiseAmpl_]:=  DistortionAmpl_, tonePairAmpl_, noiseAmpl_]:=

  Module[  Module[

    {margin,testdata,order,  {margin, testdata, order,

     filter2,filter3,filters,  filter2, filter3, filters,

     caldata,error,  caldata, error,

     responses2,responses3,  responses2, responses3,

     correctionFilters2,correctionFilters3,correctionFilters,  correctionFilters2, correctionFilters3, correctionFilters,

     distorted,corrected},  distorted, corrected},

    Print[″Version0.3″];  Print[″Version0.3″];

    (*generate second-order random distortion filters*)  (*generate second-order random distortion filters*)

    print[″Generate'filter2':″];  print["Generate'filter2':"];

    order=2:  order=2:

    filter2=GenFilters[distortFilterLen,order,spread];  filter2 = GenFilters[distortFilterLen, order, spread];

    (*generate third-order random distortion filters*)  (*generate third-order random distortion filters*)

    Print[″Generate'filter3':″];  Print["Generate'filter3':"];

    order=3;  order=3;

    filter3=GenFilters[distortFilterLen,order,spread];  filter3 = GenFilters[distortFilterLen, order, spread];

    (*combine filter data*)  (*combine filter data*)

    filters={filter2,filter3};  filters = {filter2, filter3};

    (*generate multi-tone test data record*)  (*generate multi-tone test data record*)

                                        Page2 Page2

                                 slavin.txt  slavin.txt

   Print[″Generate′testdata′:″];  Print[″Generate′testdata′:″];

   margin=(distortFilterLen-1)+(correctFilterLen-1);  margin=(distortFilterLen-1)+(correctFilterLen-1);

   testdata=GenTest[testLen,mrgin,  testdata=GenTest[testLen, mrgin,

                     testFreqLo,testFreqHi,testFreqStep];  ... testFreqLo, testFreqHi, testFreqStep];

   (*generate a set of cal data tone pairs*)  (*generate a set of cal data tone pairs*)

   print[″Generate'caldata':″];  print["Generate'caldata':"];

   cal data=DistortCal[filters,analysisLen,freqPairs,  cal data = DistortCal[filters, analysisLen, freqPairs,

                          distortionAmpl,tonePairAmpl,noiseAmpl];  distortionAmpl, tonePairAmpl, noiseAmpl];

   (*process the cal data to get filter responses*)  (*process the cal data to get filter responses*)

   error=10^-12;  error=10^-12;

   correctionFilters=  correctionFilters=

   ProcessData[caldata,calFreqLo,calFreqHi,correctFilterLen,error];  ProcessData[caldata, calFreqLo, calFreqHi, correctFilterLen, error];

   (*distort the test data using the original filters*)  (*distort the test data using the original filters*)

   print[″Generate′distorted':″];  print["Generate'distorted':"];

   distorted=DistortData[testdata,filters,  distorted=DistortData[testdata, filters,

                          distortionAmpl,tonePairAmpl,noiseAmpl];  distortionAmpl, tonePairAmpl, noiseAmpl];

   (*plot the distorted signal*)  (*plot the distorted signal*)

   PlotunwindowedFFT[Take[distorted,testLen]];  PlotunwindowedFFT[Take[distorted, testLen]];

   Print[″Generate′corrected':″];  Print["Generate'corrected':"];

   corrected=CorrectData[distorted,correctionFilters];  corrected = CorrectData[distorted, correctionFilters];

   (*plot the corrected signal*)  (*plot the corrected signal*)

   PlotUnwindowedFFT[Take[corrected,testLen]];  PlotUnwindowedFFT[Take[corrected, testLen]];

  ]  ]

(*aliases data set by first finding data mod n,and then  (*aliases data set by first finding data mod n, and then

   wrapping data>n/2 to n-data*)  wrapping data>n/2 to n-data*)

AliasF[data_,n_]:=  AliasF[data_, n_]:=

 Module[  Module[

    {len,modData,i},  {len, modData, i},

    len=Length[data];  len=Length[data];

    modData=Mod[data,n];  modData = Mod[data,n];

    Return[Table[Min[modData[[i]],n-modData[[i]],{i,1,len}]];  Return[Table[Min[modData[[i]], n-modData[[i]], {i, 1, len}]];

  ]  ]

(*Expand distortion product*)  (*Expand distortion product*)

AllTerms[i_,order_]:=  AllTerms[i_, order_] :=

  Module[  Module[

    {t,tt,j,q0,q1,q2,q3,q3a,q4,q5,q6,q7,q8,terms,len},  {t, tt, j, q0, q1, q2, q3, q3a, q4, q5, q6, q7, q8, terms, len},

    If[order=0,  If[order=0,

       Return[{0}];  Return[{0}];

      ];  ];

    q0=TrigReduce[(Cos[(i-1)tt]+Cos[(i+1)tt])^order];  q0=TrigReduce[(Cos[(i-1)tt]+Cos[(i+1)tt])^order];

    (*extract tt variable outside as a common factor for each cos term*)  (*extract tt variable outside as a common factor for each cos term*)

    q1=q0/.Cos[a_]:>Cos[Apart[a]];  q1=q0/.Cos[a_]:>Cos[Apart[a]];

    (*expand into seperate terms*)  (*expand into separate terms*)

    q2=Expand[q1];  q2 = Expand[q1];

    q3=Table[q2[[j]],{j,1,Length[q2]}];  q3 = Table[q2[[j]], {j, 1, Length[q2]}];

    (*find the cosine terms only,discard their coefficients,and convert  (*find the cosine terms only, discard their coefficients, and convert

       any DC term to 0*)  any DC term to 0*)

    q4=Table[If[NumericQ[q3[[j]]],0,q3[[j]]/(q3[[j]]/.tt->0)],  q4=Table[If[NumericQ[q3[[j]]], 0, q3[[j]]/(q3[[j]]/.tt->0)],

               {j,1,Length[q3]}];        {j, 1, Length[q3]}];

    (*eliminate the Cos[]arount each term*)  (*eliminate the Cos[]around each term*)

    q6=q4/.Cos[a_]:>Apart[a];  q6=q4/.Cos[a_]:>Apart[a];

    (*form(k*i+m)*tt->k*i+m for integer k,m*)  (*form(k*i+m)*tt->k*i+m for integer k, m*)

    q7=q6/.a_*tt:>a;  q7=q6/.a_*tt:>a;

                                   Page3 Page3

                                Slavin.txt  Slavin.txt

    q8=q7;  q8=q7;

    (*make i term positive:if k is -ve,then its derivative is -ve*)  (*make i term positive:if k is -ve,then its derivative is -ve*)

    terms=Table[If[D[q8[[j]],i]<0,-q8[[j]],q8[[j]]],{j,1,Length[q8]}];  terms=Table[If[D[q8[[j]], i]<0, -q8[[j]], q8[[j]]], {j, 1, Length[q8]}];

    Return[Expand[terms]];  Return[Expand[terms]];

  ]  ]

(*  (*

 *    *  * * *

 *S is an approximation to the inverse of the Hessian,G.  *S is an approximation to the inverse of the Hessian, G.

 *  *

 *BFGS iteration is:  *BFGS iteration is:

 *                  T           T       T          T  * T T T T

 *                ga S ga  dx dx   dx ga S+S ga dx  * ga S ga dx dx dx ga S+S ga dx

 *  S[k+1]=S+(1+--------)------  -(------------------)  * S[k+1]=S+(1+-------)------ -(------------------) 

 *                   T       T             T      * T T T T

 *                 dx ga   dx ga         dx ga  * dx ga dx ga dx ga

 *               T     T           T        T          T  * T T T T T T T T

 *            (dx ga+ga S ga)dx dx    dx ga S+S ga dx  * (dx ga+ga S ga)dx dx dx ga S+S ga dx

 *        =S+----------------------- -(------------------)  * =S+----------------------- -(------------------) 

 *                     T    2                  T      * T T 2 T T

 *  *

                      (dx ga)                 dx ga  dx ga

 *  *

 *                       T             T          T  * T T T

 *  If:v1=s ga,v2=dx ga,v3=v1 dx =S ga dx  * If: v1=s ga, v2=dx ga, v3=v1 dx =S ga dx

 *  then:  * then:

 *                   T         T     T  * T T T

 *             (v2+ga v1)dx dx    (v3+v3)  * (v2+ga v1)dx dx (v3+v3)

 *  S[k+1]=S+----------------- - --------  * S[k+1]=S+----------------- - -------- 

 *                     2  * 2

 *                  (v2)             v2  * (v2) v2

 *  *

 *Note:SetPrecision[]is used to compensate for the gradual loss in  *Note: SetPrecision[] is used to compensate for the gradual loss in

 *accuracy that Mathematica imposes on iterative calculations.  *accuracy that Mathematica imposes on iterative calculations. 

 *)  *)

BFGS[x0_,vars_,gradients_,objectiveFunc_,epsi_,maxIterations_]:=  BFGS[x0_,vars_,gradients_,objectiveFunc_,epsi_,maxIterations_]:=

  Module[  Module[

    {len,k,x,S,g,err,ds,a,ax,dx,xnew,g1,ga,v1,v2,v3,part0,part1,part2,  {len, k, x, S, g, err, ds, a, ax, dx, xnew, g1, ga, v1, v2, v3, part0, part1, part2,

     eTable,rTable,dxdxT,max,subst,residual},  eTable, rTable, dxdxT, max, subst, residual},

    len=Length[x0];  len=Length[x0];

    k=0;  k=0;

    (*convert 1-D list to a 2-D column vector*)  (*convert 1-D list to a 2-D column vector*)

    x=Transpose[SetPrecision[{x0},39]];  x = Transpose[SetPrecision[{x0}, 39]];

    (*S[k]is an approximation to the inverse of the modified Hessian of  (*S[k] is an approximation to the inverse of the modified Hessian of

       e2[x]at x=x[k]*)  e2[x]at x=x[k]*)

    S=IdentityMatrix[len];(*S is a square matrix and always symmetric*)  S=IdentityMatrix[len]; (*S is a square matrix and always symmetric*)

    g=GradFunc[x,vars,gradients];(*returns a gradient column vector*)  g = GradFunc[x, vars, gradients]; (*returns a gradient column vector*)

    err=Norm[g];(*returns sqrt of sum of squares of elements of g*)  err=Norm[g]; (*returns sqrt of sum of squares of elements of g*)

    eTable=Table[0,{maxIterations}];  eTable = Table[0, {maxIterations}];

    rTable=Table[-40.0,{maxIterations}];  rTable = Table[-40.0, {maxIterations}];

    While[(err>epsi)&&(k<maxIterations),  While[(err>epsi)&&(k<maxIterations),

        ds=-S.g;(*ds is a direction column vector*)     ds=-S.g; (*ds is a direction column vector*) 

        (*scalar′a′line search result*)  (*scalar'a'line search result*)

        ax=FletcherLineSearch[x,ds,vars,gradients,objectiveFunc];  ax = FletcherLineSearch[x, ds, vars, gradients, objectiveFunc];

        a=SetPrecision[ax,39];  a = SetPrecision[ax,39];

        dx=a*ds;(*dx is a column vector*)  dx=a*ds; (*dx is a column vector*)

        xnew=x+dx;(*new column vector result*)    xnew=x+dx; (*new column vector result*)

        g1=GradFunc[xnew,vars,gradients];(*column vector result*)  g1 = GradFunc[xnew, vars, gradients]; (*column vector result*)

        ga=g1-g;(*also a column vector*)      ga = g1-g; (*also a column vector*)

        (*dx.Transpose[dx] is a square symmetric matrix*)  (*dx.Transpose[dx] is a square symmetric matrix*)

        dxdxT=dx.Transpose[dx];  dxdxT = dx.Transpose[dx];

        v1=s.ga;(*also a column vector*)  v1=s.ga; (*also a column vector*)

                                        Page 4 Page 4

                                Slavin.txt  Slavin.txt

      v2[=(Ttanspose[ga].dx)[[1]][[1]];(*v2 is scalar*)  v2[=(Ttanspose[ga].dx)[[1]][[1]]; (*v2 is scalar*)

      If[v2==0.0,  If[v2==0.0,

         Print[″BFGS error:v2=″,v2];      Print[″BFGS error:v2=″, v2]; 

         Print[″Iteration:″,k];      Print[″Iteration:″,k]; 

         Print[″v2=″,v2];      Print[″v2=″, v2]; 

         Print[″g=″,g];      Print[″g=″,g]; 

         Print[″S=″,S];      Print[″S=″,S]; 

         Print[″Determinant[S]=″,Det[S]];  Print[″Determinant[S]=″, Det[S]];

         Print[″Inverse[S]=″,Inverse[S]];      Print[″Inverse[S]=″, Inverse[S]]; 

         Print[″ds=″,ds];      Print[″ds=″,ds]; 

         Print[″a=″,a];      Print[″a=″, a]; 

         Print[″dx=″,dx];      Print[″dx=″,dx]; 

         Print[″xnew=″,xnew];      Print[″xnew=″,xnew]; 

         Print[″g1=″,g1];      Print[″g1=″,g1]; 

         Print[″ga=″,ga];      Print[″ga=″,ga]; 

         Abort[];  Abort[];

        ];  ];

       v3=v1.Transpose[dx];(*v3 is a square matrix*)  v3=v1.Transpose[dx]; (*v3 is a square matrix*)

       (*Transpose[ga].v1 is a scalar,so part0 is scalar*)  (*Transpose[ga].v1 is a scalar, so part0 is scalar*)

       part0=(v2+(Transpose[ga].v1)[[1]][[1]])/(v2^2);  Part0=(v2+(Transpose[ga].v1)[[1]][[1]])/(v2^2);

       part1=par0*dxdxT;(*part1 is square symmetric*)    part1=par0*dxdxT; (*part1 is square symmetric*)

       (*any matrix added to its transpose is always square symmetric*)  (*any matrix added to its transpose is always square symmetric*)

       part2=(v3+Transpose[v3])/v2;(*part2 is square symmetric*)  Part2=(v3+Transpose[v3])/v2; (*part2 is square symmetric*)

       (*S(old and new)is square symmetric*)  (*S(old and new)is square symmetric*)

        S=SetPrecision[S+part1-part2,39];  S = SetPrecision[S+part1-part2, 39];

        x=SetPrecision[xnew,39];  x = SetPrecision[xnew, 39];

        g=SetPrecision[g1,39];  g = SetPrecision[g1, 39];

        subst=-Table[vars[[j]]->x[[j]][[1]],{j,1,len}];  Subst=-Table[vars[[j]]->x[[j]][[1]],{j,1,len}];

        residual=Log[objectiveFunc/.subst];  residual = Log[objectiveFunc/.subst];

        err=Norm[dx];  err = Norm[dx];

        (*Print[″iteration=″,k,″,dx=″,err];*)  (*Print[″iteration=″,k,″,dx=″,err];*)

        (*Print[″x=″,Flatten[x]];*)  (*Print[″x=″, Flatten[x]];*)

        k+=1;  k+=1;

        eTable[[k]]=err;  eTable[[k]]=err;

        rTable[[k]]=residual;  rTable[[k]]=residual;

        If[residual<-40.0,  If[residual<-40.0,

           Break[];  Break[];

          ];  ];

       ];  ];

    If[k==maxIterations,  If [k==maxIterations,

        (*Print[″BFGS Failed to converge.Final vector:″,x];*)  (*Print[″BFGS Failed to converge.Final vector:″,x];*)

        Return[];  Return[];

       ];  ];

    (* Print[″Total iterations=″,k,″,Line error=″,err];*)  (*Print[″Total iterations=″, k,″, Line error=″, err];*)

    (* Print[″Finished:x=″,Flatten[x]];*)  (*Print[″Finished:x=″, Flatten[x]];*)

    Return[Flatten[x]];  Return[Flatten[x]];

  ]  ]

(**)  (**)

CorrectData[data_,filters_]:=  CorrectData[data_, filters_]:=

  Module[  Module[

    {maxOrder,len,c,sum,j,nrSamples,samples,t},  {maxOrder, len, c, sum, j, nrSamples, samples, t},

    maxOrder=Length[filters];  maxOrder = Length[filters];

    len=Length[filters[[1,1]]];  len=Length[filters[[1,1]]];

    c=(len-1)/2;  c = (len-1)/2;

    sum=0;  sum=0;

    For[j=1,j<=maxorder,++j,  For[j=1, j<=maxorder, ++j,

        sum+=GenDistortion[data,filters[[j]]];    sum + = GenDistortion[data, filters[[j]]];

      ];  ];

                                       Page5 Page5

                           Slavin.txt  Slavin.txt

   nrSamples=Length[sum];  nrSamples = Length[sum];

   Print[″nrSamples=″,nrSamples];  Print[″nrSamples=″, nrSamples];

   samples=Take[data,{c+1,nrSamples+c}]-sum;  samples = Take[data, {c+1, nrSamples+c}]-sum;

   Return[samples];  Return[samples];

  ]  ]

(*make real tap filter have the required DC'delay′(in sample units,  (*make real tap filter have the required DC'delay'(in sample units,

   where 0 is the first tap or sample.Usually DCdelay=Length[tans]/2  where 0 is the first tap or sample.Usually DCdelay=Length[tans]/2

   is used*)  is used*)

DCadjust[realtaps_,DCdelay_]:=  DCadjust[realtaps_, DCdelay_]:=

  Module[  Module[

      {newtaps,taps,i,sum1,sum2,offset,div},  {newtaps, taps, i, sum1, sum2, offset, div},

      taps=Length[realtaps];  taps = Length[realtaps];

      sum1=Sum[irealtaps[[i+1]],{i,1,taps-1}];  sum1 = Sum[irealtaps[[i+1]], {i, 1, taps-1}];

      sum2=Sum[realtaps[[i+1]],{i,0,taps-1}];  sum2 = Sum[realtaps[[i+1]], {i, 0, taps-1}];

      div=taps*(DCdelay-(taps-1)/2);  div = taps * (DCdelay-(taps-1)/2);

      If[div==0.0,  If[div==0.0,

         Print[″DCadjust divide by zero.″];  Print[″DCadjust divide by zero.″];

         Abort[];  Abort[];

        ];  ];

      offset=(sum1-sum2*DCdelay)/div;  offset=(sum1-sum2*DCdelay)/div;

      Print[″offset=″,offset];  Print[″offset=″, offset];

      newtap=realtaps+offset;  newtap=realtaps+offset;

      Return[newtaps];  Return[newtaps];

     ]  ]

(*find the′delay'of a filter at DC*)  (*find the'delay'of a filter at DC*)

DCdelay[realtaps_]:=  DCdelay[realtaps_]:=

  Module[  Module[

      {sumc,sumci,i,taps},  {sumc, sumci, i, taps},

      (*calculate the dc delay without Arg[]aliasing.*)  (*calculate the dc delay without Arg[]aliasing.*)

      taps=Length[realtaps];  taps = Length[realtaps];

      sumc=Sum[realtaps[[i+1]],{i,0,taps-1}];    sumc = Sum[realtaps[[i+1]], {i, 0, taps-1}];

      If[sumc==0.0,  If[sumc==0.0,

         Print[″DCdelay divide by zero.″];  Print[″DCdelay divide by zero.″];

         Abort[];  Abort[];

        ];  ];

      sumci=Sum[realtaps[[i+1]]i,{i,1,taps-1}];  sumci=Sum[realtaps[[i+1]]i, {i, 1, taps-1}];

      Return[N[sumci/sumc]];  Return[N[sumci/sumc]];

    ]  ]

Delays[list_,n_]:=  Delays[list_,n_]:=

  Module[  Module[

      {i,L,len,reals,angle,diff,offset,items,complex,     {i, L, len, reals, angle, diff, offset, items, complex,

      delay,radiansPerSample,prevAngle,newDelay},  delay, radiansPerSample, prevAngle, newDelay},

      L=Length[list];  L = Length[list];

      len=n/2;  len=n/2;

      items=len+1;  Items=len+1;

      reals=Join[list,Table[0,{i,1,n-L}]];  Reals=Join[list, Table[0, {i, 1, n-L}]];

      complex=Take[Fourier[reals,{FourierParameters->{-1,1}}],items];  complex = Take[Fourier[reals, {FourierParameters->{-1, 1}}], items];

      delays=Table[0,{items}];  delays = Table[0, {items}];

      delays[[1]]=DCdelay[list];  Delays[[1]]=DCdelay[list];

      For[i=1,i<items,++i,  For[i=1, i<items, ++i,

          If[Abs[complex[[i+1]]]<10^-12,  If[Abs[complex[[i+1]]]<10^-12,

             delays[[i+1]]=delays[[i]],  Delays[[i+1]]=delays[[i]],

           (*else*)  (*else*)

             radiansPerSample=N[Pi*i/len];  ` radiansPerSample=N[Pi*i/len];

             delay=delays[[i]];  delay = delays[[i]];

             prevAngle=delay*radiansPerSample;       prevAngle = delay * radiansPerSample;

             angle=Mod[Arg[complex[[i+1]]],pi,prevAngle-Pi/2];  angle = Mod[Arg[complex[[i+1]]], pi, prevAngle-Pi/2];

                                       Page6 Page6

                                     Slavin.txt  Slavin.txt

              newDelay=angle/radiansPerSample;  newDelay=angle/radiansPerSample;

              delays[[i+1]]=newDelay;  Delays[[i+1]]=newDelay;

             ];  ];

          ];  ];

       (* possible oversampling to interpolate*)  (* possible oversampling to interpolate*)

       For[i=1,i<len,++i,      For[i=1, i<len, ++i, 

           If[Abs[complex[[i+1]]]<10^-12,  If[Abs[complex[[i+1]]]<10^-12,

              delays[[i+1]]=(delays[[i]]′+delays[[i+2]])/2;  Delays[[i+1]]=(delays[[i]]′+delays[[i+2]])/2;

             ];  ];

         ];  ];

       Return[delays-(L-1)/2];  Return[delays-(L-1)/2];

     ]  ]

(*  (*

 * design filters to correct ADC output.  * design filters to correct ADC output. 

 * DesignFilters[] works on the output of ProcessCalData  * DesignFilters[] works on the output of ProcessCalData

 *)  *)

DesignFilters[data_,correctionFilterLen_]:=  DesignFilters[data_, correctionFilterLen_]:=

  Module[  Module[

      {fi,samples,freqs,start,end,skip,i,j,freqIndex,ampl,temp,cycle,  {fi, samples, freqs, start, end, skip, i, j, freqIndex, ampl, temp, cycle,

       refDlyA,refDlyB,dly,qq,K,logsize,logFreqs,mags,parts,filters,    refDlyA, refDlyB, dly, qq, K, logsize, logFreqs, mags, parts, filters,

       nrVars,gainA,gainB,delays,totalGains,xx,sortList,sorted      nrVars, gainA, gainB, delays, totalGains, xx, sortList, sorted

       prev,next,permute,undef,modified,odd},   prev, next, permute, undef, modified, odd},

      xx=data;  xx=data;

      freqs=Length[xx]-1;(*input is oflength 2^m+1*)  freqs=Length[xx]-1; (*input is oflength 2^m+1*)

      logFreqs=Log[2,freqs];    logFreqs = Log[2, freqs];

      If[!IntegerQ[logfreqs],  If [! IntegerQ[logfreqs],

         Print[Length[xx]-1 is not a power of 2.″];  Print[Length[xx]-1 is not a power of 2.″];

         Abort[];  Abort[];

        ];  ];

      logSize=logFreqs+3;  logSize=logFreqs+3;

      samples=2^logSize;  samples = 2^logSize;

      skip=samples/(2*freqs);  skip=samples/(2*freqs);

      Print[″skip=″,skip];  Print[″skip=″, skip];

      Print[″***************** correction phase ******************″];  Print[″******************************************″];

      undef=-2;  undef=-2;

      start=end=undef;  start=end=undef;

      For[fi=0,fi<=freqs,++fi,  For[fi=0, fi<=freqs, ++fi,

          i=fi+1;  i=fi+1;

          If[Length[xx[[i]]]==0,  If[Length[xx[[i]]]==0,

             If[(start!=undef)&&(end==undef),  If[(start!=undef)&&(end==undef),

                end=fi-1;  end=fi-1;

               ];  ];

             ,(*else*)   , (*else*) 

             If[start==undef,  If[start==undef,

                start=fi;  start=fi;

               ];  ];

             ];  ];

           ];  ];

      order=0;(*default is set later*)  Order=0; (*default is set later*)

      Print[″start=″,start,″,end=″,end];  Print[″start=″, start, ″, end=″, end];

      For[fi=start,fi<=end,++fi,  For[fi=start, fi<=end, ++fi,

          i=fi+1;  i=fi+1;

          freqIndex=fi*skip;    freqIndex = fi*skip;

          cycle=N[samples/freqIndex];  `` cycle=N[samples/freqIndex];

          If[fi==start,  If[fi==start,

             nrVars=Length[xx[[i]]];  nrVars = Length[xx[[i]]];

             order=(nrVars-1)/2;  Order=(nrVars-1)/2;

                                   page7 page7

                               Slavin.txt  Slavin.txt

      odd=False;  odd=False;

      ,(*else*)  , (*else*)

      (*a previous result exists*)  (*a previous result exists*)

      prev=Table[xx[[i-1,order+1+j]],{j,1,order}];  Prev=Table[xx[[i-1, order+1+j]], {j, 1, order}];

      next=Tabl[xx[[i,order+1+j]],{j,1,order};    next = Tabl[xx[[i, order+1+j]], {j, 1, order};

      {permute,modified,odd}=MatchMod[prev,next,cycle];  {permute, modified, odd} = MatchMod[prev, next, cycle];

      xx[[i]]=Flatten[{xx[[i,1]],  xx[[i]]=Flatten[{xx[[i,1]],

                         Table[xx[[i,1+permute[[j]]]],{j,1,order}],  Table[xx[[[i,1+permute[[j]]]],{j,1,order}],

                         modified}];  modified}];

     ];  ];

   If[xx[[i,1]]<0.0  If[xx[[i,1]]<0.0

      xx[[i,1]]=-xx[[i,1]];  xx[[i,1]]=-xx[[i,1]];

      odd=!odd;  odd=! odd;

     ];  ];

   If[odd,  If[odd,

      If[xx[[i,order+2]]>0.0,  If[xx[[i, order+2]]>0.0,

         xx[[i,order+2]]-=cycle*0.5,  xx[[i, order+2]]-=cycle*0.5,

         xx[[i,order+2]]+=cycle*0.5  xx[[i, order+2]]+=cycle*0.5

        ];  ];

      ];  ];

   (* Print[″end:xx[[″,i,″]]=″,xx[[i]]];*)  (*Print[″end:xx[[″,i,″]]=″,xx[[i]]];*)

   ];  ];

(*initialize uncalibrated regions to allow later matrix transpose*)  (*initialize uncalibrated regions to allow later matrix transpose*)

For[fi=0,fi<start,++fi,  For[fi=0, fi<start, ++fi,

    i=fi+1;  i=fi+1;

    xx[[i]]=Table[0,{2*order+1}];  xx[[i]]=Table[0,{2*order+1}];

  ];  ];

For[fi=end+1,fi<=freqs,++fi,  For[fi=end+1, fi<=freqs, ++fi,

    i=fi+1;  i=fi+1;

    xx[[i]]=Table[0,{2*order+1}];  xx[[i]]=Table[0,{2*order+1}];

  ];  ];

qq=Transpose[xx];  qq = Transpose[xx];

K=qq[[1]];  K=qq[[1]];

Print[″K:″];  Print[″K:″];

PlotFreq[K,start,end];  PlotFreq[K, start, end];

For[j=1,j<=order.++j,  For[j=1, j<=order.++j,

    Print[″Amplitude″,j];  Print["Amplitude", j];

    PlotFreq[qq[[1+j]],start,end];  PlotFreq[qq[[1+j]], start, end];

  ];  ];

For[j=1,j<=order,++j,  For[j=1, j<=order, ++j,

    Print[″Delay″,j];  Print[″Delay″,j];

    PlotFreq[qq[[order+1+j]],start,end];  PlotFreq[qq[[order+1+j]], start, end];

  ];  ];

(*gainA^(order-1)*gainB=K,gainA applies to allfilters except one  (*gainA^(order-1)*gainB=K, gainA applies to allfilters except one

   which uses gainB*)  which uses gainB*)

totalGains=Take[K,{start+1,end+1}];  totalGains = Take[K, {start+1, end+1}];

gainA=Abs[totalGains]^(1/order);  gainA=Abs[totalGains]^(1/order);

gainB=totalGains/(gainA^(order-1));  gainB=totalGains/(gainA^(order-1));

delays=Table[Take[qq[[j+order+1]],{start+1,end+1}],{j,1,order}];  delays=Table[Take[qq[[j+order+1]], {start+1, end+1}], {j, 1, order}];

filters=Table[Fj]terDesign[If[j==order,gainB,gainA],delays[[j]  filters=Table[Fj]terDesign[If[j==order, gainB, gainA], delays[[j]

                freqs,start,correctionFilterLen],{j,1,order}];      freqs, start, correctionFilterLen], {j, 1, order }];

For[j=1,j<=order,++j,  For[j=1, j<=order, ++j,

    ListPlot[filters[[j]],{Plotjoined->True,PlotRange->All}];  ListPlot[filters[[j]], {Plotjoined->True, PlotRange->All}];

  ];  ];

mags=Table[Magnitude[filters[[i]],samples],{i,1,order}];  mags = Table[Magnitude[filters[[i]], samples], {i, 1, order}];

parts=Table[Take[mags[[j]],{1,1+freqs*skip,skip}],{j,1,order}];  parts=Table[Take[mags[[j]],{1,1+freqs*skip,skip}],{j,1,order}];

Print[″Original Combined amplitude response:″];  Print[″Original Combined amplitude response:″];

PlotFreq[K,start,end];  PlotFreq[K, start, end];

Print[econstructed combned response:″];  Print[econstructed combined response:″];

                              Page8 Page8

                                      Slavin.txt  Slavin.txt

      ampl=Product[parts[[i]],{j,1,order}];  ampl = Product[parts[[i]],{j,1,order}];

      PlotFreq[amp],start,end];  PlotFreq[amp], start, end];

      Print[″Amplitude response difference:″];  Print[″Amplitude response difference:″];

      PlotFre[K-amp],start,end];  PlotFre[K-amp],start,end];

      refDlys=Table[GenDelay[fi]ters[[j]],2*freqs],{j,1,order}];  refDlys=Table[GenDelay[fi]ters[[j]],2*freqs],{j,1,order}];

      For[j=1,j<=order,++j,  For[j=1, j<=order, ++j,

          Print[″Reconstructed delay response″,j,″:″];  Print[″Reconstructed delay response″,j,″:″];

          PlotRawDelay[refDlys[[j]]];  PlotRawDelay[refDlys[[j]]];

        ];  ];

      Return[filters];  Return[filters];

    ]  ]

(*single frequency DFT with gain normalization,returns a complex value*)  (*single frequency DFT with gain normalization, returns a complex value*)

DFT[data_,m_]:=  DFT[data_,m_]:=

  Module[  Module[

    {len,sum,t},  {len, sum, t},

    len=Length[data];  len=Length[data];

    sum=0;  sum=0;

    For[t=0,t<len,++t,  For[t=0, t<len, ++t,

       sum+=(Exp[I*2*pi*m*t/len] data[[t+1]]);(*1-based array indexing*)     sum+=(Exp[I*2*pi*m*t/len] data[[t+1]]); (*1-based array indexing*)

      ];  ];

    Return[2sum/len];  Return[2sum/len];

  ]  ]

(*  (*

 *Generates a broad-spectrum set of distorted calibration data.  *Generates a broad-spectrum set of distorted calibration data. 

 *′filters′={filter2,filter3,...}  *'filters' = {filter2, filter3, ...}

 *where filter2={{<taps>},{<taps>}  *where filter2={{<taps>}, {<taps>}

 *wherefilter3={{<taps>},{<taps>},{<taps>}}  *wherefilter3={{<taps>},{<taps>},{<taps>}} 

 *and each list<taps>has the same length′len′(must be odd).  *and each list<taps>has the same length′len′(must be odd). 

 *For example,before runnning Distortcal[],with  *For example, before running Distortcal[], with

 *′distortFilterLen=63;′and′spread=4.0;′  *'distortFilterLen=63;'and'spread=4.0;'

 *filter2=GenFilters[distortFilterLen,2,spread];  *filter2=GenFilters[distortFilterLen, 2, spread];

 *filter3=GenFilters[distortFilterLen,3,spread];  *filter3=GenFilters[distortFilterLen, 3, spread];

 *filters={filter2,filter3};  *filters={filter2, filter3};

 *′sx′is the output data record length for each test frequency pair.  *′sx′is the output data record length for each test frequency pair. 

 *′freqs′is one more than the number of output data frequency  *'freqs'is one more than the number of output data frequency

 *sets,e.g.for 127 sets,freqs=128.  *sets, e.g.for 127 sets, freqs=128. 

 *Note sx/freqs must be integer.  *Note sx/freqs must be integer. 

 *′distortion is the distortion level in output lsb units  *′distortion is the distortion level in output lsb units

 *′signal′is the two-tone amplitude in output lsb units.  *‘signal’is the two-tone amplitude in output lsb units. 

 *′noise′is the added noise standard deviation in output lsb units.  *′noise′is the added noise standard deviation in output lsb units. 

 *Values that match the records acquired for the AD6645 are;  *Values that match the records acquired for the AD6645 are;

 *DataGen[filters,1024,128,0.04,15000.0,2.0];  *DataGen[filters, 1024, 128, 0.04, 15000.0, 2.0];

 *)  *)

DistortCal[fiters_,sx_,freqs_,distortion_,signal_,nois_]:=  DistortCal[fiters_, sx_, freqs_, distortion_, signal_, noise_]:=

  Module[  Module[

    {error,order,q,span,data,i,j,len,qfreq,f1,f2,phase1,phase2,  {error, order, q, span, data, i, j, len, qfreq, f1, f2, phase1, phase2,

     sines,samples,t,c,sum,maxOrder},  sines, samples, t, c, sum, maxOrder},

    maxOrder=Lenqth[filters];  maxOrder = Lenqth[filters];

    len=Length[filters[[1,1]]];  len=Length[filters[[1,1]]];

    error=False;  error=False;

    If[!IntegerQ[sx],  If [! IntegerQ[sx],

       Print[″Analysis length is not integer.″];  Print["Analysis length is not integer."];

       error=True;  error=True;

      ];  ];

    If[!IntegerQ[freqs],  If [! IntegerQ[freqs],

       Print[″Frequency range is not integer.″];  Print[″Frequency range is not integer.″];

       error=True;  error=True;

                                       Page9 Page9

                                        Slavin.txt  Slavin.txt

      ];  ];

    If[!IntegerQ[len],  If [! IntegerQ[len],

       Print[″Filter lengths are not integer."];  Print[″Filter lengths are not integer.”];

       error=True;  error=True;

      ];  ];

    If[Mod[sx,4]!=0,  If[Mod[sx,4]! = 0,

       print[″Analysis length is not a multiple of 4.″];  print[″Analysis length is not a multiple of 4.″];

       error=True;  error=True;

      ];  ];

    If[Mod[sx,freqs]!=0,  If[Mod[sx, freqs]! = 0,

       Print[″Analysis length is not a multiple of the number of″  Print[″Analysis length is not a multiple of the number of″

             ″frequencies.n″];  "frequencies.n"];

       error=True;  error=True;

      ];  ];

    If[!OddQ[len],  If [! OddQ[len],

       Print[″Filter lengths are not odd.″];  Print["Filter lengths are not odd."];

       error=True;  error=True;

      ];  ];

    If[error,  If[error,

      Abort[];  Abort[];

     ];  ];

    c=(len+1)/2;  c=(len+1)/2;

    q=2.0*Pi/sx;  q=2.0*Pi/sx;

    span=sx/(2*freqs);  span=sx/(2*freqs);

    data=Table[0,{freqs-1}];  data = Table[0,{freqs-1}];

    For[i=1,i<freqs,++i,  For[i=1, i<freqs, ++i,

        qfreq=span*i;  qfreq=span*i;

        f1=qfreq-1;  f1=qfreq-1;

        f2=qfreq+1;  f2=qfreq+1;

        phase1=Random[Rea],{0,2*pi},10];  phase1 = Random[Rea], {0, 2*pi}, 10];

        phase2=Random[Rea],{0,2*pi},10];  Phase2 = Random[Rea], {0, 2*pi}, 10];

        (*Length[sines]=sx+len-1*)  (*Length[sines]=sx+len-1*)

        sines=Table[(Cos[q*f1*t-phase1]+Cos[q*f2*t-phase2]),  Sines=Table[(Cos[q*f1*t-phase1]+Cos[q*f2*t-phase2]),

                      {t,0,sx+len-2}];  {t,0,sx+len-2}];

        (*Length[samples]=Length[sines]+1-len=sx*)  (*Length[samples]=Length[sines]+1-len=sx*)

        sum=0;  sum=0;

        For[j=1,j<=maxOrder,++j,  For[j=1, j<=maxOrder, ++j,

            sum+=GenDistortion[sines,filters[[j]]];    sum + = GenDistortion[sines, filters[[j]]];

          ];  ];

        samples=distortion*sum;  samples=distortion*sum;

        samples+=Table[Gaussian[0,noise],{t,1,sx}];  samples+=Table[Gaussian[0, noise], {t, 1, sx}];

        samples+=signal*Take[sines,{c,sx+c-1}]    samples+=signal*Take[sines, {c, sx+c-1}] 

        (*output highest frequencies first*)  (*output highest frequencies first*)

        data[[Freqs-i]]=samples;  data[[Freqs-i]]=samples;

      ];  ];

    Return[data];  Return[data];

  ]  ]

(**)  (**)

DistortData[data_,filters_,distortion_,signal_,noise_]:=  DistortData[data_, filters_, distortion_, signal_, noise_]: =

  Module[  Module[

    {maxOrder,len,c,sum,j,nrSamples,samples,t},  {maxOrder, len, c, sum, j, nrSamples, samples, t},

    maxOrder=Length[filters];  maxOrder = Length[filters];

    len=Length[filters[[1,1]]];  len=Length[filters[[1,1]]];

    c=(len-1)/2;  c = (len-1)/2;

    sum=0;  sum=0;

    For[j=1,j<=maxOrder,++j,  For[j=1, j<=maxOrder, ++j,

        sum+=GenDistortion[data,filters[[j]]];    sum + = GenDistortion[data, filters[[j]]];

      ];  ];

    nrSamples=Length[sum];  nrSamples = Length[sum];

                                       Page10 Page10

                                       Slavin.txt  Slavin.txt

    Print[″nrSamples=″,nrSamples];  Print[″nrSamples=″, nrSamples];

    samples=distortion*sum;  samples=distortion*sum;

    If[noise!=0,  If [noise! = 0,

       samples+=Table[Gaussian[0,noise],{t,1,nrSamples}];  samples+=Table[Gaussian[0, noise], {t, 1, nrSamples}];

      ];  ];

    samples+=signal* Take[data,{c+1,nrSamples+c}];  samples+=signal* Take[data, {c+1, nrSamples+c}];

    Return[samples];  Return[samples];

  ]  ]

(*  (*

 *′symbVars′is the list of symbolic variables;  *'symbVars'is the list of symbolic variables;

 *   Flatten[{k,Table[a[j],{j,1,order}],Table[d[j],{j,1,order}}];  * Flatten[{k, Table[a[j], {j, 1, order}], Table[d[j], {j, 1, order}}];

 *′ix′is the index symbol to use(passed in at a higher level).  *′ix′is the index symbol to use(passed in at a higher level). 

 *′sx′is the symbolic time scale factor.  *′sx′is the symbolic time scale factor.

 *′dft′is a symbolic variable that is expanded to a list,used internally  *'dft'is a symbolic variable that is expanded to a list, used internally

 *   and also returned as the list′dfts′.  * and also returned as the list′dfts′. 

 *Returns;  *Returns;

 *′symbolicBins′:a list of IM and harmonic frequences as a functi on of the  *'symbolicBins': a list of IM and harmonic frequencies as a function on of the

 *   frequency index′ix′.  * frequency index'ix'.

 * ′e2′: a symbolic error equation as a function of ix,sx,symbVars  * ′e2′: a symbolic error equation as a function of ix, sx, symbVars

 *    and′dfts′.  * and'dfts'.

 *′g':a list of symboli gradient equations that are derivatives of  *′g’: a list of symboli gradient equations that are derivatives of

 *   ′e2′with respect to each of the′symbVars'variable list.  * 'e2'with respect to each of the'symbVars'variable list. 

 *′dfts′:a list of symbolic variables:{dft[1],dft[2],...}  *'dfts': a list of symbolic variables: {dft[1], dft[2],...} 

 *)  *)

DoInit[symbVars_,ix_,sx_,dft_]:=  DoInit[symbVars_, ix_, sx_, dft_]:=

  Module[  Module[

    {e2,g,j,nrAnalysisBins,symbolicBins,nrVars,dfts,dft,p},  {e2, g, j, nrAnalysisBins, symbolicBins, nrVars, dfts, dft, p},

    (*  (*

     *Create the symbolic expressions for the objective function e2  *Create the symbolic expressions for the objective function e2

     *and all its partial derivatives with respect to 'vars′.    *and all its partial derivatives with respect to 'vars'. 

     *Note:only really needs to be called once for multiple analysis  *Note: only really needs to be called once for multiple analysis

     *frequencies,as the results are purely symbolic.    *frequencies, as the results are purely symbolic. 

     *)  **)

    {symbolicBins,p}=Terms[ix,sx,symbVars];  {symbolicBins, p} = Terms[ix, sx, symbVars];

    nrAnalysisBins=Length[symbolicBins];  nrAnalysisBins = Length[symbolicBins];

    dfts=Table[dft[j],{j,1,nrAnalysisBins}];  dfts = Table[dft[j], {j, 1, nrAnalysisBins}];

    (*e2 is the symbolic sum of the squares of the differences between the  (*e2 is the symbolic sum of the squares of the differences between the

       predicted vlues′p′and′dfts'at each analysis bin*)    predicted vlues'p'and'dfts'at each analysis bin*)

    e2=Sum[(p[[j]][[1]]-Re[dfts[[j]]])^2+  e2=Sum[(p[[j]][[1]]-Re[dfts[[j]]])^2+

            (p[[j]][[2]]-Im[dfts[[j]]])^2,{j,1,nrAnalysisBins}];  (p[[j]][[2]]-Im[dfts[[j]]])^2,{j,1,nrAnalysisBins}];

    (*calculate symbolic partial derivatives*)  (*calculate symbolic partial derivatives*)

    nrVars=Length[symbVars];  nrVars = Length[symbVars];

    g=Table[D[e2,symbVars[[j]]],{j,1,nrvars}];  g = Table[D[e2, symbVars[[j]]], {j, 1, nrvars}];

    Return[{symbolicBins,e2,g,dfts}];  Return[{symbolicBins, e2, g, dfts}];

  ]  ]

(*  (*

 *′e2′is symbolic error equation.  *′e2′is symbolic error equation. 

 *′g′is symbolic gradiente equation.  *′g′is symbolic gradiente equation. 

 *′dfts′is array of symbolic dft results.  *′dfts′is array of symbolic dft results. 

 *′symbVars′is list of veriables that BGGS is attempting to solve.  *′symbVars′is list of veriables that BGGS is attempting to solve. 

 *′y′is list of dft results.  *′y′is list of dft results. 

 *′x′is set of start values for BFGS.  *′x′is set of start values for BFGS. 

 *′sx′is samples symbol ′s′is actual sample value.  *′sx′is samples symbol ′s′is actual sample value. 

 *′ix′is frequency index symbol,′i′is actual index value.  *'ix'is frequency index symbol,'i'is actual index value. 

 *′acc′  is BFGS accuracy goal.  *‘acc’ is BFGS accuracy goal.

 *′maxIterations′limits BFGS search time.  *'maxIterations'limits BFGS search time. 

                                         Page11 Page11

                                     Slavin.txt  Slavin.txt

 *)  *)

Dosolve[e2_,g_,dfts_,symbVars_,y0_,x_,sx_,s_,ix_,i_,acc_,  Dosolve[e2_, g_, dfts_, symbVars_, y0_, x_, sx_, s_, ix_, i_, acc_,

         maxIterations_]:=  MaxIterations_]:=

  Module[  Module[

    {e2n,gn,j,nrAnalysisBins,subst,substx,xnew,subst2,residual,len,y},  {e2n, gn, j, nrAnalysisBins, subst, substx, xnew, subst2, residual, len, y},

    y=SetPrecision[y0,39];  y = SetPrecision[y0, 39];

    nrAnalysisBins=Length[y];  nrAnalysisBins = Length[y];

    (*evaluate the symbolic expressions with the known constants*)  (*evaluate the symbolic expressions with the known constants*)

    substx=Table[dfts[[j]]->y[[j]],{j,1,nrAnalysisBins}];  substx = Table[dfts[[j]]->y[[j]],{j,1,nrAnalysisBins}];

    subst=Flatten[{sx->s,jx->i,substx}];  Subst = Flatten[{sx->s, jx->i, substx}];

    e2n=e2/.subst;  e2n=e2/.subst;

    gn=g/.subst;  gn=g/.subst;

    xnew=BFGS[x,symbVars,gn,e2n,acc,maxIterations];  xnew=BFGS[x,symbVars,gn,e2n,acc,maxIterations];

    len=Length[xnew];  len = Length[xnew];

    subst2=Table[symbVars[[j]]->xnew[[j]],{j,1,len}];  Subst2=Table[symbVars[[j]]->xnew[[j]],{j,1,len}];

    residul=e2n/.subst2;  Residul=e2n/.subst2;

    Return[{xnew,residual}];  Return[{xnew, residual}];

  ]  ]

ExpFunc[q_]:=If[q<-100,0,Exp[q]]  ExpFunc[q_]:=If[q<-100, 0, Exp[q]]

(*takes sparce gain and delay lists,places them in a′size'length list  (*takes sparse gain and delay lists, places them in a'size'length list

   at″start′(zero based),for iterative filter calculations*)  at "start'(zero based), for iterative filter calculations*)

FilterDesign[gain_,dlyin_,size_,start_,requiredtaps_]:=  FilterDesign[gain_, dlyin_, size_, start_, requiredtaps_]:=

  Module[  Module[

      {l1,l2,ampl,delay,dly,n,taps,nrtaps,offset,i,j,  {l1, l2, ampl, delay, dly, n, taps, nrtaps, offset, i, j,

       fftsize,deviation,avgdev,min,bestTaps},  fftsize, deviation, avgdev, min, bestTaps},

      l1=Length[gain];  l1=Length[gain];

      l2=Length[dlyin];  l2=Length[dlyin];

      If[l1!=l2,  If[l1! = l2,

         Print[″Missmatched gain and delay list lengths.″];  Print["Missmatched gain and delay list lengths."];

         Abort[];  Abort[];

        ];  ];

      If[EvenQ[requiredtaps],  If[EvenQ[requiredtaps],

         Print[″Number of taps must be odd.″];  Print[″Number of taps must be odd.″];

         Abort[];  Abort[];

        ];  ];

      If[(start<=0)||((start+l1)>=size)  If[(start<=0)||((start+l1)>=size)

         Print[″start and size values illegal for″,l1,″gains and delays.″];  Print["start and size values illegal for", l1, "gains and delays."];

         Abort[];  Abort[];

        ];  ];

     dly=dlyin+size;(*center the delays*)  dly=dlyin+size; (*center the delays*)

     n=size+1;  n=size+1;

     ampl=Flatten[{Table[0,{start}],gain,Table[0,{n-start-l1}]}];  ampl = Flatten[{Table[0, {start}], gain, Table[0, {n-start-l1}]}];

     delay=Flatten[{Table[size,{start}],dly,Table[size,{n-start-l2}]}];  delay=Flatten[{Table[size,{start}],dly,Table[size,{n-start-l2}]}];

     If[Length[ampl]!=n,  If[Length[ampl]! = n,

        Print[″Internalerror:Length[ampl]=″,Length[ampl],″,n=″,n];  Print[″Internalerror:Length[ampl]=″, Length[ampl],″,n=″,n];

        Abort[];  Abort[];

       ];  ];

     If[Length[delay]!=n,  If[Length[delay]! = n,

        Print[″Internal error:Length[delay]=″,Length[delay],″,n=″,n];  Print[″Internal error:Length[delay]=″, Length[delay],″,n=″,n];

        Abort[];  Abort[];

       ];  ];

     fftsize=2*size;  fftsize=2*size;

     offset=Floor[reqiredtaps/2];  offset=Floor[reqiredtaps/2];

     min=Infinity;  min=Infinity;

     For[j=0,j<100,++j,(*note:Break[] for small j in loop*)  For[j=0, j<100, ++j, (*note:Break[] for small j in loop*)

         taps=Taps[ampl,delay];  Taps = Taps[ampl, delay];

         nrtaps=Length[taps];  nrtaps = Length[taps];

         (*set coeffcients outside desired filter size to zero  (*set coefficients outside desired filter size to zero

                                     Page12 Page12

                                Slavin.txt  Slavin.txt

        For[i=0,i<fftsize,++i,  For[i=0, i<fftsize, ++i,

            If[(i<(size-offset))||(i>=(size+offset)),  If[(i<(size-offset))||(i>=(size+offset)),

               taps[[i+1]]=0;  Taps[[i+1]]=0;

              ];  ];

         ];  ];

       {ampl,delay}=Response[taps];  {ampl, delay} = Response[taps];

       (* overwrite gain and delay with original values in critical  (* overwrite gain and delay with original values in critical

           region*)  region*)

        deviation=0.0;  deviation=0.0;

        For[i=start,i<start+l1,++i,  For[i=start, i<start+l1, ++i,

            deviation+=Abs[delay[[i+1]]-dly[[i-start+1]]];  deviation+=Abs[delay[[i+1]]-dly[[i-start+1]]];

          ];  ];

        avgdev=deviation/(l1+1);  Avgdev=deviation/(l1+1);

        If[avgdev<min,  If[avgdev<min,

           min=avgdev;  min=avgdev;

           bestTaps=taps;  bestTaps = taps;

          ];  ];

        Print[″Loop″,j,″:average absolute delay deviation=″,avgdev];  Print[″Loop″,j,″:average absolute delay deviation=″,avgdev];

        If[j==25,  If[j==25,

           Break[];  Break[];

          ];  ];

        For[i=start,i<start+l1,++i,  For[i=start, i<start+l1, ++i,

            ampl[[i+1]]=gain[[i-start+1]];  Ampl[[i+1]]=gain[[i-start+1]];

            delay[[i+1]]=dly[[i-start+1]];  Delay[[i+1]]=dly[[i-start+1]];

          ];  ];

        For[i=0,i<start,++i,      For[i=0, i<start, ++i,

            delay[[i+1]]=delay[[start+1]];  Delay[[i+1]]=delay[[start+1]];

          ];  ];

       ];  ];

     taps=Table[bestTaps[[i+1]],{i,size-offset,size+offset}];  Taps = Table[bestTaps[[i+1]], {i, size-offset, size+offset}];

     dcdelay=DCdelay[taps];  dcdelay = DCdelay[taps];

     margin=Floor[0.45 requiredtaps];  margin=Floor[0.45 requiredtaps];

     If[dcdelay<margin,  If[dcdelay<margin,

        Print[″limiting lower,″];  Print[″limiting lower,″];

        taps=DCadjust[taps,margin];  Taps = DCadjust[taps, margin];

        {ampl,delay}=Response[taps],  {ampl, delay} = Response[taps],

       (*else*)  (*else*)

        If[dcdelay>=requiredtaps-margin,  If[dcdelay>=requiredtaps-margin,

           Print[″limiting upper,″];       Print[″limiting upper,″];

           taps=DCadjust[taps,requiredtaps-margin-1];  Taps = DCadjust[taps, required taps-margin-1];

           {ampl,delay}=Respons[taps];  {ampl, delay} = Respons[taps];

          ];  ];

        ];  ];

      Return[taps];  Return[taps];

    ]  ]

(*x and ds are 2-D column vectors,′vars′is a list of variables in the  (*x and ds are 2-D column vectors, 'vars' is a list of variables in the

   gradients(derivatives of the objective function).Return the objective  Gradients(derivatives of the objective function). Return the objective

   function value at vars=x*)  function value at vars=x*)

FletcherLineSearch[x_,ds_,vars_,gradients_,objectiveFunc_]:=  FletcherLineSearch[x_, ds_, vars_, gradients_, objectiveFunc_]:=

  Module[  Module[

    {m,tau,rho,sigma,gamma,mhat,epsilon,xk,s,f0,gk,deltaf0,dk,aL,aU,fL,dfL,  {m, tau, rho, sigma, gamma, mhat, epsilon, xk, s, f0, gk, deltaf0, dk, aL, aU, fL, dfL,

     a0,a0hat,a0Lhat,a0Uhat,gtemp,df0,deltaa0,alpha,div},  a0, a0hat, a0Lhat, a0Uhat, gtemp, df0, deltaa0, alpha, div},

    m=0;  m=0;

    sigma=0.1;  sigma=0.1;

    tau=Min[sigma,0.1]:(*tau<=sigma and tau<=0.1*)  tau=Min[sigma, 0.1]: (*tau<=sigma and tau<=0.1*)

    rho=sigma;(*rho<=slgma*)  rho=sigma; (*rho<=slgma*)

    gamma=0.75;  gamma=0.75;

    mhat=400;  mhat=400;

    epsilon=1.0*10^-10;  Epsilon=1.0*10^-10;

    xk=x;(*xk is a column vector*)  xk=x; (*xk is a column vector*)

    s=ds;(*′s′a column vector*)  s=ds; (*'s'a column vector*)

                                    Page13 Page13

                                  Slavin.txt  Slavin.txt

(*step 1: evaluate fk and gk at k=0.f0 is a scalar,g0 is a column  (*step 1: evaluate fk and gk at k=0.f0 is a scalar,g0 is a column

   vector*)  vector*)

f0=ObjectiveFunc[xk,vars,objectiveFunc];  f0 = ObjectiveFunc[xk, vars, objectiveFunc];

gk=GradFunc[xk,vars,gradients];(*gk is acolumn vector*)  gk = GradFunc[xk, vars, gradients]; (*gk is a column vector*)

m+=2;  m+=2;

deltaf0=f0;  deltaf0=f0;

(*step2:initialize the search*)  (*step2:initialize the search*)

dk=s;(*dk is a column vector*)  dk=s; (*dk is a column vector*)

aL=0.0;  aL=0.0;

aU=1.0**10^99;  aU=1.0**10^99;

fL=f0;  fL=f0;

dfL=(Trranspose[gk].dk)[[1]][[1]];  dfL=(Trranspose[gk].dk)[[1]][[1]];

If[Abs[dfL]>epsilon,  If[Abs[dfL]>epsilon,

   If[div==0.0,  If[div==0.0,

      Print[″FletcherLineSearch divide by dfL=0.0″];  Print[″FletcherLineSearch divide by dfL=0.0″];

      Abort[];  Abort[];

     ];  ];

   a0=-2.0*deltaf0/dfL;  a0=-2.0*deltaf0/dfL;

   ,  ,

   a0=1.0;  a0=1.0;

  ];  ];

If[(a0×10^-9)||(a0>1.0),  If[(a0×10^-9)||(a0>1.0),

   a0=1.0;  a0=1.0;

  ];  ];

(*step3:  *)  (*step3: *)

While[True,  While[True,

   deltak=a0*dk;(*deltak is a column vector*)  deltak=a0*dk; (*deltak is a column vector*)

   f0=ObjectiveFunc[xk+deltak,vars,objectiveFunc];  f0 = ObjectiveFunc[xk+deltak, vars, objectiveFunc];

   m+=1;  m+=1;

   If[(f0>(fL+rho*(a0-aL)*dfL))&&  If[(f0>(fL+rho*(a0-aL)*dfL))&&

      (Abs[fL-f0]>epsilon)&&(m<mhat),  (Abs[fL-f0]>epsilon)&&(m<mhat),

      If[a0<aU,  If[a0<aU,

         aU=a0;  aU=a0;

        ];  ];

      div=2.0*(fL-f0+(a0-aL)*dfL);  div=2.0*(fL-f0+(a0-aL)*dfL);

      If[div==0.0,  If[div==0.0,

         Print[″FletcherLineSearch divide by div=0.0″];  Print[″FletcherLineSearch divide by div=0.0″];

         Abort[];  Abort[];

        ];  ];

      a0hat=aL+(dfL*(a0-aL)^2)/div;  a0hat=aL+(dfL*(a0-aL)^2)/div;

      a0Lhat=aL+tau*(aU-aL);  a0Lhat=aL+tau*(aU-aL);

      If[a0hat<a0Lhat,  If[a0hat<a0Lhat,

         a0hat=a0Lhat;  a0hat=a0Lhat;

        ];  ];

      a0Uhat=aU-tau*(aU-aL);  a0Uhat=aU-tau*(aU-aL);

      If[a0hat>a0Uhat,  If[a0hat>a0Uhat,

         a0hat=a0Uhat;  a0hat=a0Uhat;

        ];  ];

      a0=a0hat;  a0=a0hat;

       (*else*)  (*else*)

      (*gtemp is a vector*)  (*gtemp is a vector*)

      gtemp=GradFunc[xk+a0*dk,vars,gradents];  gtemp = GradFunc[xk+a0*dk,vars,gradents];

      df0=(Transpose[gtemp].dk)[[1]][[1]];  df0 = (Transpose[gtemp].dk)[[1]][[1]];

      m+=1;  m+=1;

      If[(df0<sigma*dfL)&&(Abs[fL-f0]>epsilon)&&  If[(df0<sigma*dfL)&&(Abs[fL-f0]>epsilon)&&

         (m<mhat)&&(dfL!=df0),  (m<mhat)&&(dfL!=df0),

         div=dfL-df0;  div = dfL-df0;

         deltaa0=(a0-aL)*df0/div;    deltaa0=(a0-aL)*df0/div;

         If[deltaa0<=0,  If[deltaa0<=0,

           a0hat=2*a0;  A0hat=2*a0;

           ,(*else*)  , (*else*)

           a0hat=a0+deltaa0;  A0hat=a0+deltaa0;

           ];  ];

                               Page14 Page14

                                Slavin.txt  Slavin.txt

           a0Uhat=a0+gamma*(aU-a0);  a0Uhat=a0+gamma*(aU-a0);

           If[a0hat>a0Uhat,  If[a0hat>a0Uhat,

              a0hat=a0Uhat;  A0hat=a0Uhat;

             ];  ];

           aL=a0;  aL=a0;

           a0=a0hat;  A0=a0hat;

           fL=f0;  fL=f0;

           dfL=df0;  dfL=df0;

           ,(*else*)  , (*else*)

           Break[];  Break[];

          ];  ];

        ];  ];

     ];  ];

   If[a0<1.0*10^-5,  If[a0<1.0*10^-5,

      alpha=1.0*10^-5;    alpha=1.0*10^-5; 

      ,(*else*)  , (*else*)

      alpha=a0;  alpha=a0;

      ];  ];

    Return[alpha];  Return[alpha];

  ]  ]

FTSize[len_,min_]:=  FTSize[len_,min_]:=

  Module[  Module[

      {},  {},

      Return[Max[min,2^Ceiling[Log[2,len]]]];  Return[Max[min, 2^Ceiling[Log[2,len]]]];

    ]  ]

Gaussian[mean_,sd_]:=  Gaussian[mean_, sd_] :=

  Module[  Module[

    {result},  {result},

    Return[sd*Sqrt[2.0]*InverseErf[Random[]]*Sign[Random[]-0.5]+mean];  Return[sd*Sqrt[2.0]*InverseErf[Random[]]*Sign[Random[]-0.5]+mean];

  ]  ]

(*finds sample delay as a function of frequency.  (*finds sample delay as a function of frequency. 

   uses ALL′list′taps-no symmetry is assumed*)  uses ALL'list'taps-no symmetry is assumed*)

GenDelay[list_,min_:16]:=  GenDelay[list_,min_:16]:=

  Module[  Module[

      {len,delays,endindex,nx},  {len, delays, endindex, nx},

      len=Length[list];  len=Length[list];

      nx=FTSize[len,min];  `nx=FTSize[len,min];

      endindex=nx/2;  endindex=nx/2;

      Return[Take[Delays[list,nx],{1,endindex+1}]];  Return[Take[Delays[list,nx],{1,endindex+1}]];

     ]  ]

(*  (*

 *distort the data for a particular filter order Length[taps].  *distort the data for a particular filter order Length[taps]. 

 *)  *)

GenDistortion[data_,taps_]:=  GenDistortion[data_, taps_] :=

  Module[  Module[

    {len,filters,flen,delay,output,i,file},  {len, filters, flen, delay, output, i, file},

    len=Length[data];  len=Length[data];

    filters=Length[taps];  filters = Length[taps];

    flen=Length[taps[[1]]];  flen = Length[taps[[1]]];

    If[EvenQ[flen],  If[EvenQ[flen],

       Print[″Filter lengths are not all odd.″];  Print["Filter lengths are not all odd."];

       Abort[];  Abort[];

      ];  ];

    For[i=1,i<=taps1,++i,  For[i=1, i<=taps1, ++i,

        len1=Length[taps[[i]]];  len1=Length[taps[[i]]];

                                            Page15 Page15

                                        Slavin.txt  Slavin.txt

        If[len1!=flen,  If[len1! =flen,

           Print[″Filter lengths are not all equal.″];  Print["Filter lengths are not all equal."];

           Abort[];  Abort[];

          ];  ];

      ];  ];

    delay=(1+flen)/2;  delay=(1+flen)/2;

    output=Table[1.0,{len-flen+1}];  output = Table[1.0, {len-flen+1}];

    For[i=1,i<=filters,++i,  For[i=1, i<=filters, ++i,

        filt=taps[[i]];  filt = taps[[i]];

        If[Length[filt]!=flen,  If[Length[filt]! =flen,

           Print[″Filter lengths are not all the same.″];  Print["Filter lengths are not all the same."];

           Abort[];  Abort[];

          ];  ];

        output*=ListConvolve[filt,data];  output*=ListConvolve[filt, data];

      ];  ];

    Return[output];  Return[output];

  ]  ]

(*generate a set of filters for a particular order of distortion*)  (*generate a set of filters for a particular order of distortion*) 

GenFilters[len_,order_,spread_]:=  GenFilters[len_, order_, spread_]:=

  Module[  Module[

    {error,taps,i,j,c},  {error, taps, i, j, c},

    error=False;  error=False;

    If[!IntegerQ[len],  If [! IntegerQ[len],

       Print[″Filter lengths are not integer.″];  Print[″Filter lengths are not integer.″];

       error=True;  error=True;

      ];  ];

    If[!OddQ[len],  If [! OddQ[len],

       Print[″Filter lengths are not odd.″];  Print["Filter lengths are not odd."];

       error=True;  error=True;

      ];  ];

    If[error,  If[error,

       Abort[];  Abort[];

      ];  ];

     c=(len+1)/2;  c = (len+1)/2;

     taps=Table[Gaussian[0,1]*ExpFunc[-Abs[(j-c)*2/spread]],  Taps=Table[Gaussian[0,1]*ExpFunc[-Abs[(j-c)*2/spread]],

                   {i,1,order},{j,1,len}];  {i, 1, order}, {j, 1, len}];

     Return[taps];  Return[taps];

   ]  ]

(*  (*

 *′samples′gives nr of output sampels(plus extra),and also fundamental  *'samples' gives nr of output sampels(plus extra), and also fundamental

 *length,so all generated sines are harmonics of the fundamental.  *length, so all generated sines are harmonics of the fundamental. 

 *′extra′gives the number of extra samples in the output record that may be  *′extra′gives the number of extra samples in the output record that may be

 *needed to compensate for convolution data loss due to filters.  *needed to compensate for convolution data loss due to filters. 

 *′freqLo′is the low normalized frequency for sine output:  *′freqLo′is the low normalized frequency for sine output: 

 *0<freqLow<0.5.The nearest higher harmonic of the′samples′frequency  *0<freqLow<0.5.The nearest higher harmonic of the'samples'frequency

 *is the lowest output frequency.  *is the lowest output frequency. 

 *′freqHi′is the high normalized frequency for sine output:  *′freqHi′is the high normalized frequency for sine output:

 *0<freqLow<0.5.The nearest lower harmonic of the′samples′frequency  *0<freqLow<0.5.The nearest lower harmonic of the'samples'frequency

 *is the higheest output frequency.  *is the highest output frequency. 

 *′freqInterval′is the normalized frequency step,also a harmonic of the  *'freqInterval'is the normalized frequency step, also a harmonic of the

 *′samples′frequency.  *‘samples’frequency. 

 *)  *)

GenTest[samples_,extra_,freqLo_,freqHi_,freqInterval_]:=  GenTest[samples_, extra_, freqLo_, freqHi_, freqInterval_]: =

  Module[  Module[

    {kInterval,kStart,kEnd,sum,x,j,t},  {kInterval, kStart, kEnd, sum, x, j, t},

    kInterval=Floor[freqInterval*samples+0.5];  kInterval=Floor[freqInterval*samples+0.5];

                                          Page16 Page16

                                     Slavin.txt  Slavin.txt

    kStart=Ceiling[freqLo*samples];  kStart = Ceiling[freqLo*samples];

    kEnd=Floor[freqHi*samples];  kEnd = Floor[freqHi*samples];

    sum=0;  sum=0;

    x=2.0*Pi/samples;  x=2.0*Pi/samples;

    For[j=kStart,j<=kEnd,j+=kInterval,  For[j=kStart, j<=kEnd, j+=kInterval,

        sum+=Table[sin[x*j*t],{t,0,samples+extra-1}];     sum+=Table[sin[x*j*t], {t, 0, samples+extra-1}];

      ];  ];

    Return[sum];  Return[sum];

  ]  ]

(*′x′is a 2-D column vector,′vars′is a list of variables in the list of  (*′x′is a 2-D column vector,′vars′is a list of variables in the list of

   ′gradients′functions which are the partial derivatives of the objective  ′gradients′functions which are the partial derivatives of the objective

   function with respect to each variable.*)  function with respect to each variable.*)

GradFunc[x_,vars_,gradients_]:=  GradFunc[x_, vars_, gradients_] :=

  Module[  Module[

    {g,subst,j,len},  {g, subst, j, len},

    len=Length[x];  len=Length[x];

    subst=Table[vars[[j]]->x[[j]][[1]],{j,1,len}];  Subst = Table[vars[[j]]->x[[j]][[1]],{j,1,len}];

    g=gradients/.subst;  g = gradients/.subst;

    Return[Transpose[{g}]];(*return a column vector as a 2-D matrix*)  Return[Transpose[{g}]]; (*return a column vector as a 2-D matrix*)

  ]  ]

IsSame[xx_]:=  IsSame[xx_]:=

  Module[  Module[

   {nrVars,order,indices,permArray,perms,same,i,j,perm,v0,v1}  {nrVars, order, indices, permArray, perms, same, i, j, perm, v0, v1}

   nrVars=Length[xx];  nrVars = Length[xx];

   order=(nrVars-1)/2;  order=(nrVars-1)/2;

   indices=Table[i,{i,1,order}];  indices = Table[i,{i,1,order}];

   permArray=Permutations[indices];  permArray = Permutations[indices];

   perms=Length[permArray];  perms = Length[permArray];

   same=False;  same=False;

   For[j=1,j<=perms,++j,  For[j=1, j<=perms, ++j,

       perm=permArray[[j]];  Perm = permArray[[j]];

       v0=perm[[1]];  v0 = perm[[1]];

       v1=pem[[2]];  v1 = pem[[2]];

       If[v1×v0,  If[v1×v0,

          same=(Chop[xx[[v0+order+1]]-xx[[v1+order+1]]]==0);  Same=(Chop[xx[[v0+order+1]]-xx[[v1+order+1]]]==0);

          If[same,  If[same,

             Break[];  Break[];

            ];  ];

         ];  ];

      ];  ];

    Return[same];  Return[same];

  ]  ]

Log10List[list_]:=  Log10List[list_]:=

  Module[  Module[

      {minv,lminv,log,i,item,L,result},  {minv, lminv, log, i, item, L, result},

      L=Length[list];  L = Length[list];

      minv=Min[list];  minv=Min[list];

      If[minv<=10^-10,  If[minv<=10^-10,

         minv=10^-10;     minv = 10^-10; 

        ];  ];

      result=TaBle[0,{L}];    result = TaBle[0,{L}]; 

      For[i=0,i<L,++i,  For[i=0, i<L, ++i,

          item=list[[i+1]];       item = list[[i+1]]; 

          If[item<minv,  If[item<minv,

             item=minv;  `item=minv;`

            ];  ];

          result[[i+1]]=20.0 Log[10,item]     result[[i+1]]=20.0 Log[10, item] 

                                       Page17 Page17

                                         Slavin.txt  Slavin.txt

        ];  ];

      Return[result];  Return[result];

    ]  ]

LogFFT[list_]:=  LogFFT[list_]:=

  [Mdule[  [Mdule[

      {i,L,magfreg,logmagf,data,bins},  {i, L, magfreg, logmagf, data, bins},

      L=Length[list];  L = Length[list];

      bins=Floor[(L+1)/2];  bins=Floor[(L+1)/2];

      magfreq=Abs [Take[Fourier[list,{FourierParameters->{-1,1}}],bins]];  magfreq = Abs[Take[Fourier[list, {FourierParameters->{-1, 1}}], bins]];

      freq=Table[N[i/L],{i,0,bins-1}];    freq=Table[N[i/L], {i, 0, bins-1}];

      logmagf=Log10List[magfreq];  ` logmagf = Log10List[magfreq];

      data=Transpose[{freq,logmagf}];  data = Transpose[{freq, logmagf}];

      Return[data];  Return[data];

    ]  ]

Magnitude[list_,n_]:=  Magnitude[list_,n_]:=

  Module[  Module[

      {i,L,reals,magfreq},  {i, L, reals, magfreq},

      L=Length[list];  L = Length[list];

      reals=Join[list,Table[0,{i,1,n-L}]];  Reals=Join[list, Table[0, {i, 1, n-L}]];

      magfreq=Abs[Take[Fourier[reals,{FourierParameters->{1,1}}],n/2+1]];  magfreq = Abs[Take[Fourier[reals, {FourierParameters->{1, 1}}], n/2+1]];

      Return[magfreq];  Return[magfreq];

    ]  ]

(*  (*

 *patt1 and patt2 numeric list lengths are equal.Find the permutation index  *patt1 and patt2 numeric list lengths are equal.Find the permutation index

 *of patt2 that minimizes the sum of the squares of the differences of patt1  *of patt2 that minimizes the sum of the squares of the differences of patt1

 *and patt2,modulo:'mod’.-Used for reorganizing phases.Also returns a  *and patt2, modulo: 'mod'.-Used for reorganizing phases. Also returns a

 *modified version of patt2 which is close to patt1,modulo′mod′。  *modified version of patt2 which is close to patt1, modulo 'mod'. the

 *For example:  *For example:

 *MatchMod[{0.2,0.5,0.8},{1.22,0.88,0.47},1]  *MatchMod[{0.2, 0.5, 0.8}, {1.22, 0.88, 0.47}, 1] 

 *yields the indicesmodified patt2,and odd status:  *yields the indicesmodified patt2, and odd status:

 *{{1,3,2},{0.22,0.47,0.88},False}  * {{1, 3, 2}, {0.22, 0.47, 0.88}, False} 

 *)  *)

MatchMod[patt1_,patt2_,mod_]:=  MatchMod[patt1_,patt2_,mod_]:=

  Module[  Module[

    {len1,len2,indices,permArra,perms,min,sum,perm,i,j,diff,index,x,new,  {len1, len2, indices, permArra, perms, min, sum, perm, i, j, diff, index, x, new,

     step,steps,total,odd},   step, steps, total, odd},

    len1=Length[patt1];  len1=Length[patt1];

    len2=Length[patt2];  len2=Length[patt2];

    If[len1!=len2,  If[len1! =len2,

       Print[″Length mismatch.″];  Print["Length mismatch."];

       Abort[];  Abort[];

      ];  ];

    indices=Table[i,{i,1,len1}]  indices=Table[i, {i, 1, len1}]

    permArray=Permutations[indices];  permArray = Permutations[indices];

    perms=Length[permArray];  perms = Length[permArray];

    min=Infinity;  min=Infinity;

    step=mod*0.5;  step=mod*0.5;

    For[j=1,j<=perms,++j,  For[j=1, j<=perms, ++j,

        sum=0;  sum=0;

        perm=permArray[[j]];  Perm = permArray[[j]];

        total=0;  total=0;

        For[i=1,i<=len1,++i,      For[i=1, i<=len1, ++i,

            diff=patt1[[i]]-patt2[[perm[[i]]]];  diff = patt1[[i]]-patt2[[perm[[i]]]];

            steps=Floor[diff/step+0.5];    steps = Floor[diff/step+0.5];

            total+=steps;  total+=steps;

            sum+=(diff-step*steps)^2;       sum+=(diff-step*steps)^2; 

                                  Page18 Page18

                                      Slavin.txt  Slavin.txt

         ];  ];

       If[sum<min,  If[sum<min,

          (*found best solution so far*)  (*found best solution so far*)

          odd=OddQ[total;(*record the odd-ness of the solution*)     odd=OddQ[total; (*record the odd-ness of the solution*) 

          index=j;  index=j;

          min=sum;  min=sum;

         ];  ];

      ];  ];

    perm=permArray[[index]];  perm = permArray[[index]];

    new=Table[x=patt2[[perm[[i]]]];  new=Table[x=patt2[[perm[[i]]]];

               x+step*Floor[(patt1[[i]]-x)/step+0.5],  x+step*Floor[(patt1[[i]]-x)/step+0.5],

               {i,1,len1}];  {i,1,len1}];

    Return[{perm,new,odd}];  Return[{perm, new, odd}];

  ]  ]

(*′x′is a 2-D column vector,′vars′is a list of all variables in the  (*′x′is a 2-D column vector,′vars′is a list of all variables in the

    objective function.Return the objective function value at vars=x*)  Objective function.Return the objective function value at vars=x*)

ObjectiveFunc[x_,vars_,objectiveFunc_]:=  ObjectiveFunc[x_, vars_, objectiveFunc_] :=

  Module[  Module[

    {subst,j,len},  {subst, j, len},

    len=Length[x];  len=Length[x];

    subst=Table[vars[[j]]->x[[j]][[1]],{j,1,len}];  Subst = Table[vars[[j]]->x[[j]][[1]],{j,1,len}];

    Return[objectiveFunc/:subst];(*return a scalar*)  Return[objectiveFunc/:subst]; (*return a scalar*)

  ]  ]

PlotColor[list_,color_]:=  PlotColor[list_, color_]:=

  Module[  Module[

      {min,max,r,g,b,data},  {min, max, r, g, b, data},

      r=color[[1]];  r = color[[1]];

      g=color[[2]];  g = color[[2]];

      b=color[[3]];  b = color[[3]];

      data={0,Transpose[list][[2]]};*always include zero*)  data={0,Transpose[list][[2]]};*always include zero*)

      max=Max[data];  max = Max[data];

      min=Min[data];  min=Min[data];

      Return[ListPlot[list,{PlotJoined->True,  Return[ListPlot[list, {PlotJoined->True,

                             GridLines->Automatic,  GridLines->Automatic,

                             PlotRange->{min,max},  PlotRange->{min,max},

                             ImageSize->600,  ImageSize->600,

                             PlotStyle->RGBColor[r,g,b]}]];  PlotStyle->RGBColor[r,g,b]}]];

    ]  ]

(*startIndex and endIndex indices(0-based)apply to the list*)  (*startIndex and endIndex indices(0-based)apply to the list*)

plotFreq[list_,startIndex_:0,endIndex_:-1]:=  plotFreq[list_, startIndex_:0, endIndex_:-1]:=

  Module[  Module[

      {i,L,delays,freq,data,idata,endi,max,min,selected},  {i, L, delays, freq, data, idata, endi, max, min, selected},

      L=Length[list];  L = Length[list];

      If[endIndex==-1,  If[endIndex==-1,

         endi=L-1,  endi=L-1,

         endi=endIndex  endi=endIndex

        ];  ];

      freq=Table[N[i/(2*(L-1))],{i,startIndex,endi}];  freq=Table[N[i/(2*(L-1))], {i, startIndex, endi}];

      selected=Take[list,{startIndex+1,endi+1}];  selected = Take[list, {startIndex+1, endi+1}];

      data=Transpose[{freq,selected}];  data = Transpose[{freq, selected}];

      idata={0,selected};(*always include zero*)  idata={0, selected}; (*always include zero*)

      max=Max[idata];  max = Max[idata];

      min=Min[idata];  min=Min[idata];

      Return[ListPlot[data,{PlotJoined->True,  Return[ListPlot[data,{PlotJoined->True,

                              GridLines->Automatic,  GridLines->Automatic,

                              PlotRange->{{0,0.5},{min,max}},  PlotRange->{{0,0.5},{min,max}},

                              ImageSize->600,  ImageSize->600,

                                        Page19 Page19

                                       Slavin.txt  Slavin.txt

                              PlotStyle->RGBColor[1,0,0]}]];  PlotStyle->RGBColor[1, 0, 0]}]];

    ]  ]

(*finds sample delay as a function of frequency.    (*finds sample delay as a function of frequency. 

   uses ALL ′list′taps -no symmetry is assumed,plot in red*)  uses ALL 'list' taps -no symmetry is assumed,plot in red*)

PlotRawDelay[delays_]:=  PlotRawDelay[delays_]:=

  Module[  Module[

      {i,len,freq,data},  {i, len, freq, data},

      len=Length[delays]-1;  len=Length[delays]-1;

      freq=Table[N[i/(2*len)],{i,0,len}];  freq=Table[N[i/(2*len)], {i, 0, len}];

      data=Transpose[{freq,delays}];  data = Transpose[{freq, delays}];

      Return[PlotColor[data,{1,0,0}]];  Return[PlotColor[data,{1,0,0}]];

    ]  ]

PlotUnwindowedFFT[list_]:=  PlotUnwindowedFFT[list_]:=

  Module[  Module[

      {},  {},

      Return[WfmColor[LogFFT[list],{1,0,0}]];  Return[WfmColor[LogFFT[list],{1,0,0}]];

    ]  ]

PolarToComplex[ampls_,angles_]:=  PolarToComplex[ampls_, angles_]:=

  Module[  Module[

      {l1,l2,fl,i,len,reals,angle,ampl,real,imag,out},  {l1, l2, fl, i, len, reals, angle, ampl, real, imag, out},

      l1=Length[ampls];  l1=Length[ampls];

      l2=Length[angles];  l2=Length[angles];

      If[l1!=l2,  If[l1! = l2,

         Print[″Missmatched amplitude and angle list lengths.″];  Print["Missmatched amplitude and angle list lengths."];

         Abort[];  Abort[];

        ];  ];

      len=l1-1;  len=l1-1;

      fl=2*len;  `fl=2*len;

      out=Table[0,{i,1,fl}];  out = Table[0,{i,1,fl}];

      For[i=0,i×len,++i,  For[i=0, i×len, ++i,

          angle=angles[[i+1]];  angle = angles[[i+1]];

          ampl=ampls[[i+1]];  ampl = ampls[[i+1]];

          real=ampl Cos[angle];  real = ampl Cos[angle];

          imag=ampl Sin[angle];  imag = ampl Sin[angle];

          out[[i+1]]=real+I imag;    out[[i+1]]=real+I imag;

          If[(i !=0),  If[(i != 0),

             out[[fl-i+1]]=real-I imag;      out[[fl-i+1]]=real-I imag; 

            ];  ];

        ];  ];

      out[[len+1]]=ampls[[len+1]];  out[[len+1]]=ampls[[len+1]];

      Return[out];  Return[out];

    ]  ]

PrAmplPhase[data_,bin_]:=  PrAmplPhase[data_, bin_]:=

  Module[  Module[

      {out,ampl,ph},  {out,ampl,ph},

      out=DFT[data,bin];  out = DFT[data, bin];

      ampl=Abs[out];  ampl = Abs[out];

      ph=Arg[out];  ph = Arg[out];

      Return[{ampl,ph}];  Return[{ampl,ph}];

    ]  ]

ProcessCalData[data_,order_,lowf_,hiF_,acc_]:=  ProcessCalData[data_, order_, lowf_, hiF_, acc_]: =

  Module[  Module[

      {fi,  {fi,

                                        Page20 Page20

                                      Slavin.txt  Slavin.txt

 delta,freqs,start,end,skip,i,j,t,freqIndex,overhang,  delta, freqs, start, end, skip, i, j, t, freqIndex, overhang,

 i1,i2,ampl,ph,len,bins,sBins,w1,w2,scaling,temp,cycle,  i1, i2, ampl, ph, len, bins, sBins, w1, w2, scaling, temp, cycle,

 amplRet,phRef,amplRatio,q,scale,  amplRet, phRef, amplRatio, q, scale,

 amplitude2,relPhase2,relDelay2,amplitude3,relPhase3,relDelay3,  amplitude2, relPhase2, relDelay2, amplitude3, relPhase3, relDelay3,

 corrPh,turns,rph,xbin,analyze1,reference,redo,d1,d2,x,y,  corrPh, turns, rph, xbin, analyze1, reference, redo, d1, d2, x, y,

 dly,dlyA,dlyB,amplA,amplB,donesomething,  dly, dlyA, dlyB, amplA, amplB, donesomething,

 descr,expected,K,logSize,logFregs,amplx,  descr, expected, K, logSize, logFregs, amplx,

 magA,magB,partAm1,partAp1,partBm1,partBp1,transpose,  magA, magB, partAm1, partAp1, partBm1, partBp1, transpose,

 delays,base,partial,de,amplI,ii,nrBins,  delays, base, partial, de, amplI, ii, nrBins,

 filter1,filter2,frBins,index,f1,f2,fs,out1,out2,out3,  filter1, filter2, frBins, index, f1, f2, fs, out1, out2, out3,

 e2,g,s,nrVars,symbolicBins,symbVars,  e2, g, s, nrVars, symbolicBins, symbVars,

 k,a,d,ix,sx,xnew,yl,allSymBins,blen,slen,numericBins,  k, a, d, ix, sx, xnew, yl, allSymBins, blen, slen, numericBins,

 dfts,dft,results,maxorde,gainA,gainB,delavA,delayB,  dfts, dft, results, maxorde, gainA, gainB, delavA, delayB,

 maxIterations,substx,jj,kk,random,  maxIterations, substx, jj, kk, random,

 residual,lowestResiduals,bestResults,startPoints,xStart,gains,  residual, lowestResiduals, bestResults, startPoints, xStart, gains,

 solutions,found,xx,qresults,solution,smallesttResidueIndex,  solutions, found, xx, qresults, solution, smallesttResidueIndex,

 sortList,sorted,state,const,maxTries,extraTries,  sortList, sorted, state, const, maxTries, extraTries,

 symbvarsW,symbolicBinsW,e2W,gW,dftsW},  symbvarsW, symbolicBinsW, e2W, gW, dftsW},

Print[″*******************************************************″];  Print[″*************************************** ********"];

Print[″****************** initialization *********************″];  Print

Print[″*******************************************************″];  Print[″*************************************** ********"];

(*Various″magic″parameters*)  (*Various″magic″parameters*) 

(*maximum tries to find a first BFGS solution.Too large means time  (*maximum tries to find a first BFGS solution. Too large means time

   may be wasted finding a solution when none can be found.Too small  may be wasted finding a solution when none can be found. Too small

   and a solution may not be found.*)  and a solution may not be found.*)

   maxTries=100;  maxTries=100;

(*extra attempts to find more BFGS solutions after the first is found.  (*extra attempts to find more BFGS solutions after the first is found. 

   Too large and time may be wasted finding additional solutions when  Too large and time may be wasted finding additional solutions when

   none exist. Too small,and a better solution can be missed.The  None exist. Too small, and a better solution can be missed.The

   probability of missing a second solution is about 1/2 per try,  Probability of missing a second solution is about 1/2 per try,

   so the probability of missing it is(1/2)^extraTries*)  So the probability of missing it is(1/2)^extraTries*)

extraTries=25;  extraTries = 25;

(*maximum BFGS iterations allowed in which to converge to a solution.  (*maximum BFGS iterations allowed in which to converge to a solution. 

   Too large and time may be wasted trying to find a BFGS solution,  Too large and time may be wasted trying to find a BFGS solution,

   too small and a solution may not be found.Typically,2nd order  too small and a solution may not be found.Typically, 2nd order

   needs<30 and 3rd order needs<80.*)  needs<30 and 3rd order needs<80.*)

maxIterations=100;  maxIterations = 100;

(*maximum number of total unique solutions at a cal frequency.  (*maximum number of total unique solutions at a cal frequency. 

   2nd order:3^2=9 solutions per group,3rd order:3^3=27 per group.  2nd order: 3^2=9 solutions per group, 3rd order: 3^3=27 per group. 

   Too larg a value and more memory is used.Too small and there is  Too larg a value and more memory is used. Too small and there is

   insufficient storage for multiple groups.I′ve never seen more than 3  Insufficient storage for multiple groups. I′ve never seen more than 3

   groups,or 3*27=81 solutions for any frequency.*)  groups, or 3*27=81 solutions for any frequency.*)

solutions=200;  solutions=200;

(*sampling frequency(MHz)*)  (*sampling frequency(MHz)*)

fs=100.0;  fs=100.0;

overhang=63;  overhang=63;

logFreqs=7;  logFreqs=7;

symbVars=  symbVars =

  Flatten[{k,Table[a[j],{j,1,order}],Table[d[j],{j,1,order}]}];  Flatten[{k, Table[a[j], {j, 1, order}], Table[d[j], {j, 1, order}]}];

{symbolicBins,e2,g,dfts}=DoInit[stmbvars,ix,sx,dft];  {symbolicBins, e2, g, dfts} = DoInit[stmbvars, ix, sx, dft];

If[(lowF<0)||(lowF>0.5)||(hiF<0)||(hiF>0.5)||  If[(lowF<0)||(lowF>0.5)||(hiF<0)||(hiF>0.5)||

   (lowF>=hiF),  (lowF>=hiF),

   Print[″low or high frequency bounds are<0 or×0.5,or″];  Print[″low or high frequency bounds are<0 or×0.5, or″];

   Print[″low frequency bound″,lowF,″is>=hidh bound″,hiF];  Print["low frequency bound", lowF, "is>=hidh bound", hiF];

   Abort[];  Abort[];

  ];  ];

Print[″sampling frequency:″,fs,″MHz″];  Print["sampling frequency:", fs, "MHz"];

logSize=logFreqs+3;(*added value must be>=3*)  logSize=logFreqs+3; (*added value must be>=3*) 

                               Page21 Page21

                             Slavin.txt  Slavin.txt

delta=1;  delta=1;

samples=2^logSize;(*power of 2*)  samples=2^logSize; (*power of 2*)

n=(2*overhang+1);(*n is odd filter length*)  n=(2*overhang+1); (*n is odd filter length*) 

len=samples+2*(n-1);(*overhang required at each end*)  len=samples+2*(n-1); (*overhang required at each end*)

If[logFreqs>logSize-3,  If[logFreqs>logSize-3,

   Print[″logFreqs must be<=logSize-3″];  Print[″logFreqs must be<=logSize-3″];

   Abort[];  Abort[];

  ];  ];

freqs=2^logFregs;(*frequencies to Nyguist. A power of 2*)  freqs=2^logFregs; (*frequencies to Nyguist. A power of 2*)

start=Max[Floor[lowF*freqs*2],1];  start=Max[Floor[lowF*freqs*2], 1];

end=Min[Ceiling[hiF*freqs*2],freqs-1];  end=Min[Ceiling[hiF*freqs*2], freqs-1];

If[start==freqs/2,  If[start==freqs/2,

   Print[″Error:start frequency evaluates to fs/2.This cannot be″  Print[″Error: start frequency evaluates to fs/2.This cannot be″

         ″used because it starts on an alias notch.″];  "used because it starts on an alias notch."];

   Abort[];  Abort[];

  ];  ];

If[end==freqs/2,  If[end==freqs/2,

   Print[″Error:end frequency evaluates to fs/2.This cannot be″  Print[″Error: end frequency evaluates to fs/2.This cannot be″

         ″used because it starts on an alias notch.″];  "used because it starts on an alias notch."];

   Abort[];  Abort[];

  ];  ];

skip=samples/(2*freqs);  skip=samples/(2*freqs);

Print[″Frequency indices:start=″,start,″,end=″,end];  Print["Frequency indices: start = ", start, ", end = ", end];

Print[″Range:0:″,freqs-1,″,index skip=″,skip];  Print["Range:0:", freqs-1, ", index skip=", skip];

(*nr of different IM and harmonic frequency bins to consider*)  (*nr of different IM and harmonic frequency bins to consider*) 

nrBins=Length[symbolicBins];  nrBins = Length[symbolicBins];

amplitude=Table[0,{i,1,freqs+1},{j,1,nrBins}];  amplitude=Table[0, {i, 1, freqs+1}, {j, 1, nrBins}];

yl=Table[0,{i,1,freqs+1},{j,1,nrBins}];  yl=Table[0,{i,1,freqs+1},{j,1,nrBins}];

bins=Table[0,{i,1,freqs+qs+1},{j,1,nrBins}];  bins=Table[0,{i,1,freqs+qs+1},{j,1,nrBins}]; 

amplRatio=Table[0.0,{i,1,freqs+1}];  amplRatio=Table[0.0,{i,1,freqs+1}];

Scaling=Table[0.0,{i,1,freqs+1}];  Scaling=Table[0.0,{i,1,freqs+1}];

descr=Table[0.0,{i,1,freqs+1}];  descr=Table[0.0,{i,1,freqs+1}]; 

allSymBins=AllTerms[ii,orde];  allSymBins = AllTerms[ii, orde];

blen=Length[allSymBins];  blen = Length[allSymBins];

dly=0.0;  dly=0.0;

redo=-1;  redo=-1;

const=2*Pi/samples;  const=2*Pi/samples;

Print[″*******************************************************″];  Print[″*************************************** ********"];

Print[″****************** DFT analysis ***********************″];  Print[″****************** DFT analysis***************************************************************

Print[″******************************************************″];  Print[″*************************************** *******"];

(*  (*

 *default x[[i]]=False indicates not measurable due to aliasing,  *default x[[i]]=False indicates not measurable due to aliasing,

 *True indicates measurable but failed to converge on search,  *True indicates measurable but failed to converge on search,

 *otherwise x[[i]]equals a list of solutions.  *otherwise x[[i]]equals a list of solutions. 

 *)  *)

x=Table[False,{i,1,freqs+1}];  x = Table[False, {i, 1, freqs+1}];

For[fi=start,fi<=end,++fi,  For[fi=start, fi<=end, ++fi,

    i=fi+1;(*offset for non-zero based array indexing*)  i=fi+1; (*offset for non-zero based array indexing*)

    index=freqs-fi;  index = freqs-fi;

    analyze1=data[[index]];  analyze1 = data[[index]];

    freqIndex=fi skip;  freqIndex = fi skip;

    i1=freqIndex-delta;  i1 = freqIndex-delta;

    i2=freqIndex+delta;  i2=freqIndex+delta;

    w1=2*Pi*i1/samples;  w1=2*Pi*i1/samples;

    w2=2*Pi*i2/samples;  w2=2*Pi*i2/samples;

                               Page 22 Page 22

                                                  Slavin.txt  Slavin.txt

    Print[″*****************************″];  Print[″****************************″];

    Print[″fi=″,fi,″,index=″,index,″,freqIndex=″,freqIndex];  Print["fi=", fi, ", index=", index, ", freqIndex=", freqIndex];

    (*look for alias collisions using all frequencies*)  (*look for alias collisions using all frequencies*)

    numericBins=allSymBins/.ii->freqIndex;  numericBins = allSymBins/.ii->freqIndex;

    sBins=Sort[AliasF[numericBins,samples]];  sBins = Sort[AliasF[numericBins, samples]];

    Print[″sBins=″,sBins];  Print[″sBins=", sBins];

    For[j=1,j<blen,++j,  For[j=1, j<blen, ++j,

        If[sBins[[j]]==sBins[[j+1]],  If[sBins[[j]]==sBins[[j+1]],

           redo=i;  Redo = i;

           Break[];  Break[];

          ];  ];

      ];  ];

    If[redo==i,  If[redo==i,

       Continue[]  Continue[]

      ];  ];

    x[[i]]=True;(*indicate measurable at i*)  x[[i]]=True; (*indicate measurable at i*)

    (*symbolicBins represents only the frequencies used for analysis,  (*symbolicBins represents only the frequencies used for analysis,

       which excludes Dc and the ibput cal frequencies themselves*)  which excludes Dc and the ibput cal frequencies themselves*)

    bins[[i]]=symbolicBins/.ix->freqIndex;  bins[[i]]=symbolicBins/.ix->freqIndex;

    Print[″bins″,order,″=″,bins[[i]]];  Print[″bins″, order, ″=″, bins[[i]]];

    (*generate timing references from signal+small distortion*)  (*generate timing references from signal+small distortion*)

    reference=analyze1^order;  reference=analyze1^order;

    temp=Abs[DFT[analyze1,i1]];  temp = Abs[DFT[analyze1, i1]];

    temp+=Abs[DFT[analyze1,i2]];  temp+=Abs[DFT[analyze1,i2]];

    scaling[[i]]=temp*0.5;  scaling[[i]]=temp*0.5;

    (*calculate amplitudes,phases and delays*)  (*calculate amplitudes, phases and delays*)

    For[j=1,j<=nrBins,++j,  For[j=1, j<=nrBins, ++j,

       xbin=bins[[i,j]];  xbin = bins[[i, j]];

       temp=DFT[analyze1,xbin];  temp = DFT[analyze1, xbin];

       {amplRef,phRef=PrAmplPhase[reference,xbin];  {amplRef, phRef = PrAmplPhase[reference, xbin];

       yl[[i,j]]=temp*Exp[-I*phRef];  yl[[i,j]]=temp*Exp[-I*phRef];

     ];  ];

   f1=N[fs*i1/samples,8];  f1=N[fs*i1/samples, 8];

   f2=N[fs*i2/samles,8];  f2=N[fs*i2/samles, 8];

   Print[″f1=″,fs-f1,″(aliased=″,f1,″),″,  Print[″f1=", fs-f1,"(aliased=", f1,"), ",

         ″f1=″,fs-f2,″(aliased=″,f2,″).″];  ″f1=″, fs-f2, ″(aliased=″, f2,″).″];

    Print[″yl[″,i,″]=″,yl[[i]]];  Print[″yl[″,i,″]=″,yl[[i]]];

    If[redo==(i-1),  If[redo==(i-1),

       redo=-1;  redo=-1;

      ];  ];

  ];  ];

Print[″**************************************************************″];  Print[″*************************************** ***************"];

Print[″************************** Optimization ***********************″];  Print[″********************************************** ***"];

Print[″**************************************************************″];  Print[″*************************************** ***************"];

search=1;(*related search radius*)  search=1; (*related search radius*)

For[fi=start,fi<=end,++fi,  For[fi=start, fi<=end, ++fi,

    Print[″*****************************″];  Print[″****************************″];

    i=fi+1;(*offset for non-zero based array indexing*)  i=fi+1; (*offset for non-zero based array indexing*)

    If[!x[[i]];  If [! x[[i]];

       Continue[];  Continue[];

      ];  ];

                             Page23 Page23

                          Slavin.txt  Slavin.txt

cycle=samples/freqIndex;  cycle=samples/freqIndex;

(*measurable*)  (*measurable*) 

freqIndex=fi*skip;  freqIndex = fi*skip;

Print[″fi=″,fi,″,freqIndex=″,freqIndex,  Print["fi=", fi, ", freqIndex=", freqIndex,

      ″,cycl delay(samples)=″,N[cycle]];  ″, cycle delay(samples) = ″, N[cycle]];

Print[″y[″,fi,″]=″,yl[[i]]];  Print[″y[″, fi, ″]=″, yl[[i]]];

lowestResiduals=Table[Intinity,{solutions}];  lowestResiduals = Table[Intinity, {solutions}];

bestResults=Table[{},{solutions}];  bestResults = Table[{}, {solutions}];

startPoints=Table[{},{solutions}];  startPoints = Table[{},{solutions}];

solution=0;  solution=0;

smallestResidueIndex=1;  smallestResidueIndex = 1;

kk=maxTries;  kk=maxTries;

nestStart={};  nestStart = {};

random=False;  random=False;

While[--kk>=0,  While[--kk>=0,

     slen=Length[x[[i-1]]];  slen = Length[x[[i-1]]];

     random=(slen==0)||(kk!=maxTries-1)||IsSame[x[[i-1]]];  random=(slen==0)||(kk!=maxTries-1)||IsSame[x[[i-1]]];

     If[random,  If[random,

        If[slen==0,  If[slen==0,

           xStart=Flatten[  xStart=Flatten[

             {0.1*(Random[]-0.5),  {0.1*(Random[]-0.5),

              Table[Exp[0.1*(Random[]-0.5)],{order}],         Table[Exp[0.1*(Random[]-0.5)],{order}], 

              Table[cycle*(Random[]-0.5)*0.5,{order}]}];  Table[cycle*(Random[]-0.5)*0.5,{order}]}];

           ,  , ,

           xStart=x[[i-1]]  xStart=x[[i-1]]

             Table[Exp[0.4*(Random[]-0.5)],{slen}];  Table[Exp[0.4*(Random[]-0.5)],{slen}];

          ];  ];

        ,  , ,

        xStart=x[[i-1]];  xStart = x[[i-1]];

       ];  ];

     {results,residual}=DoSolve[e2,g,dfts,symbVars,  {results, residual} = DoSolve[e2, g, dfts, symbVars,

                                  yl[[i]],xStart,sx,  yl[[i]], xStart, sx,

                                  samples,ix,freqIndex,acc,  samples, ix, freqIndex, acc,

                                  maxIterations];  maxIterations];

     If[Length[results]<=0,  If[Length[results]<=0,

        Continue[];  Continue[];

       ];  ];

     If[!random,  If [! random,

        Print[″result=″,results];      Print[″result=″,results]; 

        Print[″residual=″,residual];  Print[″residual=″, residual];

        x[[i]]=results;  x[[i]]=results;

        Break[];  Break[];

       ];  ];

    (*center the angles as much as possible*)  (*center the angles as much as possible*)

    xStart=results;  xStart = results;

    parity=0;  parity=0;

    For[jj=1,jj<=order,++]],  For[jj=1, jj<=order, ++]],

        xx=Floor[[results[[order+jj+1]]*(2.0/cycle))+1/2];  xx=Floor[[results[[order+jj+1]]*(2.0/cycle))+1/2];

        xStart[[order+jj+1]]-=(xx*cycle*0.5);  xStart[[order+jj+1]]-=(xx*cycle*0.5);

        parity+=xx;  Parity+=xx;

       ];  ];

     If[OddQ[parity],  If[OddQ[parity],

        xStart[[1]]=-xStart[[1]];  xStart[[1]]=-xStart[[1]];

       ];  ];

     (*reoptimize from more centered starting point*)  (*reoptimize from more centered starting point*)

     {results,residual}=DoSolve[e2,g,dfts,symbVars,  {results, residual} = DoSolve[e2, g, dfts, symbVars,

                                  yl[[i]],xStart,sx,  yl[[i]], xStart, sx,

                                  samples,ix,freqIndex,acc,  samples, ix, freqIndex, acc,

                                  maxIterations];  maxIterations];

     If[Length[results]<=0,  If[Length[results]<=0,

        Continue[];  Continue[];

                              Page24 Page24

                         Slavin.txt  Slavin.txt

   ];  ];

 sortList={Table[results[[jj+order+1]],{jj,1,order}],  sortList={Table[results[[jj+order+1]], {jj, 1, order}],

            Table[results[[jj+1]],{jj,1,order}],        Table[results[[jj+1]],{jj,1,order}], 

            Table[xStart[[jj+order+1]],{jj,1,order}],       Table[xStart[[jj+order+1]],{jj,1,order}], 

            Table[xStart[[jj+1]],{jj,1,order}]}:        Table[xStart[[jj+1]], {jj, 1, order}]}:

(*rank solutions in order of second sub-list (angles)*)  (*rank solutions in order of second sub-list (angles)*)

sorted=Transpose[Sort[Transpose[sortList]]];  sorted=Transpose[Sort[Transpose[sortList]]];

results=Flatten[{results[[1]],sorted[[2]],sorted[[1]]}];  results=Flatten[{results[[1]], sorted[[2]], sorted[[1]]}];

xStart=Flatten[{xStart[[1]],sorted[[4]],sorted[[3]]}];  xStart = Flatten[{xStart[[1]], sorted[[4]], sorted[[3]]}];

(*see if solution found already*)  (*see if solution found already*)

found=False;  found=False;

For[jj=1,jj<=solutions,++jj,  For[jj=1, jj<=solutions, ++jj,

    If[lowestResiduals[[jj]]==Infinity,  If[lowestResiduals[[jj]]==Infinity,

       (*reached end of valid solutions,nothing found*)  (*reached end of valid solutions,nothing found*)

       Break[];  Break[];

       ,(*else*)  , (*else*)

       If[Chop[lowestResiduals[[jj]]-residual]==0.0,  If[Chop[lowestResiduals[[jj]]-residual]==0.0,

          found=True;  found=True;

          Break[];(*solution already found*)  Break[]; (*solution already found*)

         ];  ];

      ];  ];

  ];  ];

If[found,  If[found,

   Continue[];  Continue[];

  ];  ];

(*no solution found*)  (*no solution found*)

If[jj>solutions,  If[jj>solutions,

   (*finding another solution when no more are allowed*)  (*finding another solution when no more are allowed*)

   Print[″*************************″,  Print["************************",

         ″Too many solutions found.″,  "Too many solutions found.",

         ″*************************″];  ″*************************″];

   Abort[];  Abort[];

  ];  ];

(*new solution,so reset loop limit*)  (*new solution, so reset loop limit*)

kk=extraTries;  kk = extraTries;

(*find index into data set with lowest error residual*)  (*find index into data set with lowest error residual*)

If[jj>1,  If[jj>1,

   If[residual<lowestResiduals[[smallestResidueIndex]],  If[residual<lowestResiduals[[smallestResidueIndex]],

      smallestResidueIndex=jj;  The smallestResidueIndex = jj;

     ];  ];

   ];  ];

(*find a multiplicity of local solutions at approximately Pi  (*find a multiplicity of local solutions at approximately Pi

   intervals on all angles*)  intervals on all angles*)

lowestResiduals[[jj]]=residual;  lowestResiduals[[jj]]=residual;

bestResults[[jj]]=results;  bestResults[[jj]]=results;

startPoints[[jj]]=xStart;  startPoints[[jj]]=xStart;

++solution;  ++solution;

Print[″Solution″,solution];  Print["Solution", solution];

Print[″Starting vector x=″,xStart];  Print[″Starting vector x=″, xStart];

Print[″Minimum at″,results];  Print["Minimum at", results];

Print[″Lowest residual error=″,residual];  Print[″Lowest residual error=″, residual];

++jj;  ++jj;

state=Table[-search,{order}];  state=Table[-search,{order}];

While[True,  While[True,

    (*find next state*)  (*find next state*)

    xStart=results;  xStart = results;

    (*Print[″state=″,state];*)  (*Print[″state=″, state];*)

    parity=0;  parity=0;

    For[xx=1,xx<=order,++xx,  For[xx=1, xx<=order, ++xx,

                           Page25 Page25

                         Slavin.txt  Slavin.txt

           parity+=state[[xx]];  Parity+=state[[xx]];

           xStart[[order+1+xx]]+=(cycle*state[[xx]]*0.5);    xStart[[order+1+xx]]+=(cycle*state[[xx]]*0.5);

          ];  ];

        If[OddQ[parity],  If[OddQ[parity],

           xStart[[1]]=-results[[1]];  xStart[[1]]=-results[[1]];

          ];  ];

        {qresults,residual}=DoSolve[e2,g,dfts,symbVars,  {qresults, residual} = DoSolve[e2, g, dfts, symbVars,

                                       y[[i]],xStart,sx,  y[[i]], xStart, sx,

                                       samples,ix,freqIndex,acc,  samples, ix, freqIndex, acc,

                                       maxIterations];  maxIterations];

         If[Length[qresults]>0,  If[Length[qresults]>0,

            If[jj>solutions,  If[jj>solutions,

               Print[″*************************″,                    

                     ″Too many solutions found.″,         "Too many solutions found.", 

                     ″*************************″];    ″***********************″];

               Abort[];  Abort[];

              ];  ];

           lowestResiduals[[jj]]=residual;  lowestResiduals[[jj]]=residual;

           bestResults[[jj]]=qresults;  BestResults[[jj]]=qresults;

           startPoints[[jj]]=xStart;  startPoints[[jj]]=xStart;

           ++jj;  ++jj;

          ];  ];

         xx=1;  xx=1;

         While[xx<=order,  While[xx<=order,

             state[[xx]]+=1;  State[[xx]]+=1;

             If[state[[xx]]<=search,  If[state[[xx]]<=search,

                Break[];  Break[];

               ];  ];

             state[[xx]]=-search;  State[[xx]]=-search;

             ++xx;        ++xx;

            ];  ];

          If[xx>order,  If[xx>order,

             Break[];  Break[];

            ];  ];

         ];(*end of While[True,]*)  ]; (*end of While[True,]*)

      ];(*end of While[--k>=0,]*)  ]; (*end of While[--k>=0,]*)

     If[random,  If[random,

        If[Length[bestResults[[1]]]==0,  If[Length[bestResults[[1]]]==0,

           Print[″Solutions not found.″];  Print["Solutions not found."];

           (*leave x[[i]]as True indicates measurable but not valid*)  (*leave x[[i]] as True indicates measurable but not valid*)

           x[[i]]=bestResults[[smallestResidueIndex]];  x[[i]]=bestResults[[smallestResidueIndex]];

          ];  ];

       ];  ];

   ];  ];

(*  (*

 *for each i,x[[i]] is either a legitimate list of solutions,or is  *for each i, x[[i]] is either a legitimate list of solutions, or is

 *boolean False indicating it is not measurable due to alias frequency  *boolean False indicating it is not measurable due to alias frequency

 *conflicts,or is True indicating it is measurable,but that a  *conflicts, or is True indicating it is measurable, but that a

 *solution hasn′t been previously tound.  *solution hasn′t been previously toound. 

 *)  *)

Print[″Filling in holes using search:″];  Print[″Filling in holes using search:″];

(*fill in holes where no solution was found*)  (*fill in holes where no solution was found*)

doneSomething=True;  doneSomething = True;

While[doneSomething,  While[doneSomething,

    doneSomething=FALSE;  doneSomething = FALSE;

    for[fi=start,fi<=end,++fi,  for[fi=start, fi<=end, ++fi,

        i=fi+1;(*offset for non-zero based array indexing*)  i=fi+1; (*offset for non-zero based array indexing*)

        If[(Length[x[[i]]]==0)&& x[[i]]],  If[(Length[x[[i]]]==0)&& x[[i]]],

           (*x[[i]]is measurable*)  (*x[[i]] is measurable*)

           freqIndex=fi*skip;      freqIndex = fi*skip; 

                               Page26 Page26

                                    Slayin.txt  Slayin.txt

                    If[(fi>start)&&(Length[x[[i-1]]]>0),  If[(fi>start)&&(Length[x[[i-1]]]>0),

                       xStart=x[[i-1]];  xStart=x[[i-1]];

                       {results,residual}=DoSolve[e2,g,dfts,symbVars,  {results, residual} = DoSolve[e2, g, dfts, symbVars,

                                                    yl[[i]],xStart,sx,  yl[[i]],xStart,sx,

                                                    samples,ix,freqIndex,acc,  samples, ix, freqIndex, acc,

                                                    maxIterations];  maxIterations];

                       If[Length[results]>0,  If[Length[results]>0,

                          x[[i]]=results;  x[[i]]=results;

                          doneSomething=True;  doneSomething=True;

                          Print[″x[″,fi,″]=″,x[[i]]];  Print[″x[″,fi,″]=″,x[[i]]];

                          Print[″residual=″,residual];  Print[″residual=″, residual];

                         ];  ];

                      ];  ];

                    If[(Length[x[[i]]]==0)&&  If[(Length[x[[i]]]==0)&&

                       (fi<end)&&(Length[x[[i+1]]]>0),  ... (fi<end)&&(Length[x[[i+1]]]>0),

                       xStart=x[[i+1]];  xStart=x[[i+1]];

                       {results,residual}=DoSolve[e2,g,dtts,symbVars,  {results, residual} = DoSolve[e2, g, dtts, symbVars,

                                                    yl[[i]],xStar,sx,  yl[[i]],xStar,sx,

                                                    samples,ix,freqIndex,  samples, ix, freqIndex,

                                                    acc,maxIterations];  acc, maxIterations];

                      If[Length[results]>0,  If[Length[results]>0,

                         x[[i]]=results;  x[[i]]=results;

                         doneSomething=True;  doneSomething=True;

                         Print[″x[″,Fi,″]=″x[[i]]];  Print[″x[″,Fi,″]=″x[[i]]];

                         Print[″residual=″,residual];  Print[″residual=″,residual];

                        ];  ];

                     ];  ];

                ];  ];

            ];  ];

        ];  ];

      Print[″Forcibly filling all renaining holes using previous valuesls:″];  Print[″Forcibly filling all renaining holes using previous valuesls:″];

      For[fi=start+1,fi<=end,++fi,  For[fi=start+1, fi<=end, ++fi,

          i=fi+1;(*offset for non-zero based array indexing*)       i=fi+1; (*offset for non-zero based array indexing*) 

          If[Lenth[x[[i]]]==0,  If[Lenth[x[[i]]]==0,

             x[[i]]=x[[i-1]];  x[[i]]=x[[i-1]];

            ];  ];

        ];  ];

      Print[″Scale output values:″];  Print[″Scale output values:″];

      (*scale as separate step to avoid problems with valid handling*)  (*scale as separate step to avoid problems with valid handling*)

      For[fi=start,fi<=end,++fi,  For[fi=start, fi<=end, ++fi,

          i=fi+1;  i=fi+1;

          If[scaling[[i]]==0.0,  If[scaling[[i]]==0.0,

             temp=(scaling[[i-1]]+scaling[[i+1]]*0.5;  Temp = (scaling[[i-1]]+scaling[[i+1]]*0.5;

             ,             

             temp=scaling[[i]];  temp = scaling[[i]];

            ];  ];

          x[[i,1]]/=(temp^order);  x[[i,1]]/=(temp^order);

          (*Print[″output:x[″,fi,″]=”,x[[i]]];*)  (*Print[″output:x[″, fi,″]=", x[[i]]];*)

        ];  ];

      Return[x];  Return[x];

    ]  ]

(*finds amplitudes and delay (in sample units)response of even length real  (*finds amplitudes and delay (in sample units) response of even length real

   tap filter*)  tap filter*)

Response[real]taps_]:=  Response[real]taps_]:=

  Module[  Module[

      {taps,dcDelay,complex,len,l1,ampls,delays,i,ampl,  {taps, dcDelay, complex, len, l1, ampls, delays, i, ampl,

       radiansPerSample,delay,prevangle,angle,diffangle,newdelay,mod,  radiansPerSample, delay, prevangle, angle, diffangle, newdelay, mod,

       scale,xtaps},  scale, xtaps},

      taps=Length[realtaps];  taps = Length[realtaps];

                                            Page27 Page27

                                  Slavin.txt  Slavin.txt

 (*Print[″realtaps=″,realtaps];*)  (*Print[″realtaps=″,realtaps];*)

 (*calculate the dc delay without Arg[] aliasing.*)  (*calculate the dc delay without Arg[] aliasing.*)

 dcDelay=DCdelay[realtaps];  dcDelay = DCdelay[realtaps];

 (*extend input to scale*taps to use a longer FFT which  (*extend input to scale*taps to use a longer FFT which

    should reduce phase wrapping ambiguities*)  should reduce phase wrapping ambiguities*)

 scale=2;  scale=2;

 xtaps=Flatten[{realtaps,Table[0,{(scale-1)taps}]}];  xtaps = Flatten[{realtaps, Table[0, {(scale-1)taps}]}];

 (*taps input returns l1=(taps/2)+1 items*)  (*taps input returns l1=(taps/2)+1 items*)

 complex=Fourier[xtaps,{FourierParameters->{1,1}}];  complex = Fourier[xtaps, {FourierParameters->{1, 1}}];

 (*Print[″complex=″,Take[complex,{1,taps*scale,scale}]];*)  (*Print[″complex=″, Take[complex, {1, taps*scale, scale}]];*)

 len=scale*taps/2;  len=scale*taps/2;

 l1=len+1;  l1=len+1;

 ampls=Table[0,{l1}];  ampls = Table[0,{l1}];

 delays=Table[0,{l1}];  delays = Table[0,{l1}];

 delays[[1]]=dcDelay;  delays[[1]] = dcDelay;

 ampls[[1]]=Abs[complex[[1]]];  ampls[[1]]=Abs[complex[[1]]];

 mod=Pi;  mod = Pi;

 (*for all non-dc frequencies*)  (*for all non-dc frequencies*)

 For[i=1,i<=len,++i,  For[i=1, i<=len, ++i,

     ampl=Abs[complex[[i+1]]];  ampl = Abs[complex[[i+1]]];

     ampls[[i+1]]=ampl;  ampls[[i+1]]=ampl;

     If[ampl<10^-12,  If[ampl<10^-12,

        (*if amplitude too small for accurate angle,use previous  (*if amplitude too small for accurate angle, use previous

           delay as this is needed by the delay reconstruction*)    delay as this is needed by the delay reconstruction*) 

        delays[[i+1]]=delays[[i]],  Delays[[i+1]]=delays[[i]],

     (* else*)  (* else*)

       (*reconstruct delay using previous delay which should  (*reconstruct delay using previous delay which should

          work well  as long as delay changes,when translated    work well as long as delay changes, when translated

          to angles,are not>Pi bwtween adjacent frequencies       to angles, are not>Pi bwtween adjacent frequencies

          at the new frequency*)  at the new frequency*)

       (*conversion ratio between delays and radians*)    (*conversion ratio between delays and radians*) 

       radiansPerSample=N[Pi*i/len];  radiansPerSample=N[Pi*i/len];

       delay=delays[[i]];(*get previous delay*)  delay = delays[[i]]; (*get previous delay*)

       (*convert previous delay to angle at new frequency*)  (*convert previous delay to angle at new frequency*)

       prevangle=delay*radiansPerSample;  Prevangle=delay*radiansPerSample;

       (*get angle at new frequency*)  (*get angle at new frequency*)

       anale=Mod[Arg[complex[[i+1]]],Pi,prevangle-Pi/2];   anale=Mod[Arg[complex[[i+1]]], Pi, prevangle-Pi/2];

       (*Print[″angle=″,angle]:*)  (*Print[″angle=″, angle]:*)

       newDelay=angle/radiansPerSample;  NewDelay = angle/radiansPerSample;

       delays[[i+1]]=newDelay;  Delays[[i+1]]=newDelay;

      ];  ];

   ];  ];

 (*where magnitude is too small,angles are unreliable,so  (*where magnitude is too small, angles are unreliable, so

    average adjacent delays to get delay instead*)  Average adjacent delays to get delay instead*)

 For[i=1,i<len,++i,  For[i=1, i<len, ++i,

     If[ampls[[i+1]]<10^-12,  If[ampls[[i+1]]<10^-12,

        delays[[i+1]]=(delays[[i]]+delays[[i+2]])/2;  Delays[[i+1]]=(delays[[i]]+delays[[i+2]])/2;

       ];  ];

   ];  ];

 If[ampls[[len+1]]<10^-12,  If[ampls[[len+1]]<10^-12,

    delays[[len+1]]=2 delays[[len]]-delays[[len-1]];  delays[[len+1]]=2 delays[[len]]-delays[[len-1]];

   ];  ];

 Return[{Take[ampls,{1,len+1,scale}],  Return[{Take[ampls, {1, len+1, scale}],

         Take[delays,{1,len+1,scale}]}];  Take[delays, {1, len+1, scale}]}];

]

                                    Page28 Page28

                                     Slavin.txt  Slavin.txt

(*in each list,first value is DC,last is at w=Pi=fs/2*)  (*in each list, first value is DC, last is at w=Pi=fs/2*)

Taps[ampls_,delays_]:=  Taps[ampls_, delays_]:=

  Module[  Module[

      {l1,l2,len,taps,angles,complex,targetDelay,realtaps},  {l1, l2, len, taps, angles, complex, targetDelay, realtaps},

      l1=Length[ampls];  l1=Length[ampls];

      l2=Length[delays];  l2=Length[delays];

      If[l1!=l2,  If[l1! = l2,

         Print[″Missmatched amplitude and delay listl lengths.″];  Print[″Missmatched amplitude and delay listl lengths.″];

         Abort[];  Abort[];

        ];  ];

      len=l1-1;  len=l1-1;

      taps=2*len;  Taps=2*len;

      angles=Table[delays[[i+1]]*i*Pi/len,{i,0,len}];  angles=Table[delays[[i+1]]*i*Pi/len, {i, 0, len}];

      (*Print[″angles=″,angles];*)  (*Print[″angles=″, angles];*)

      complex=PolaroComplex[ampls,angles];  complex = PolaroComplex[ampls, angles];

      (*Print[″complex=″,complex];*)  (*Print[″complex=″, complex];*)

      realtaps=InverseFourier[complex,{FourierParameters->{1,1}}];  realtaps = InverseFourier[complex, {FourierParameters->{1, 1}}];

      Return[realtaps];  Return[realtaps];

    ]  ]

(*  (*

 *Finds symbolic IM and harmonic frequency terms using the frequency  *Finds symbolic IM and harmonic frequency terms using the frequency

 *index and samples symbols 'ix’and'sx'.’vars’is the list of variables  *index and samples symbols 'ix'and'sx'.'vars'is the list of variables

 *defining the filter product to use.It is of the form;  *defining the filter product to use.It is of the form;

 *  Flatten[{k,Table[a[j],{j,1,order}],Table[d[j],{j,1,order}]}];  * Flatten[{k, Table[a[j], {j, 1, order}], Table[d[j], {j, 1, order}]}];

 *)  *)

Terms[ix_,sx_,vars_]:=  Terms[ix_,sx_,vars_]:=

  Module[  Module[

    {r0,r1,r2,r3,r4,r5,t,tt,a,b,c,j,cost,sint,len,i1,i2,p,q,nrVars,order,  {r0, r1, r2, r3, r4, r5, t, tt, a, b, c, j, cost, sint, len, i1, i2, p, q, nrVars, order,

     q0,q1,q2,q3,q3a,q4,q5,q6,q7,q8,terms,j1,j2,t1,t2},  q0, q1, q2, q3, q3a, q4, q5, q6, q7, q8, terms, j1, j2, t1, t2},

    nrVars=Length[vars];  nrVars = Length[vars];

    order=(nrVars-1)/2;  order=(nrVars-1)/2;

    If[!InteggerQ[order],  If [! IntegerQ[order],

       Print[″Vars list must be of from:″  Print[″Vars list must be of from:″

             ″{kx,ax0,ax1,...,axn,dx0,dx1,...,dxn}″];    "{kx,ax0,ax1,...,axn,dx0,dx1,...,dxn}"];

       Abort[];  Abort[];

      ];  ];

    q0=TrigReduce[(Cos[(ix-1)tt]+Cos[(ix+1)tt])^order];  q0=TrigReduce[(Cos[(ix-1)tt]+Cos[(ix+1)tt])^order];

    (*extract tt variable outside as a common factor for each cos term*)  (*extract tt variable outside as a common factor for each cos term*)

    q1=q0/.Cos[a_]:>Cos[Apart[a]];  q1=q0/.Cos[a_]:>Cos[Apart[a]];

    (*expand into seperate terms*)  (*expand into separate terms*)

    q2=Expand[q1];  q2 = Expand[q1];

    (*make into a list*)  (*make into a list*)

    q3=Table[q2[[j]],{j,1,Length[q2]}];  q3 = Table[q2[[j]], {j, 1, Length[q2]}];

    (*eliminate DC frequencies from list*)  (*eliminate DC frequencies from list*)

    q4=Table[If[NumericQ[q3[[j]]],0,q3[[j]]/(q3[[j]]/.tt->0)],  q4=Table[If[NumericQ[q3[[j]]], 0, q3[[j]]/(q3[[j]]/.tt->0)],

               {j,1,Length[q3]}          {j, 1, Length[q3]} 

    (*eliminate the Cos[] arount each term*)  (*eliminate the Cos[] around each term*)

    q5=q4/.Cos[a_]:>Apart[a];  q5=q4/.Cos[a_]:>Apart[a];

    (*form(k*ix+m)*tt->k*ix+m for integer k,m*)  (*form(k*ix+m)*tt->k*ix+m for integer k, m*)

    q6=q5/.a-*tt:>a;  q6=q5/.a-*tt:>a;

    (*make ix term positive:if k is-ve,then its derivative is-ve*)  (*make ix term positive:if k is-ve,then its derivative is-ve*)

    q7=Table[If[D[q6[[j]],ix]<0,-q6[[j]],q6[[j]]],{j,1,Length[q6]}];  q7=Table[If[D[q6[[j]],ix]<0,-q6[[j]],q6[[j]]],{j,1,Length[q6]}];

    (*eliminate lower-order harmonics from term list*)  (*eliminate lower-order harmonics from term list*)

    If[order>=2,  If[order>=2,

       j1=j2=1;  j1=j2=1;

       (*a higher order contains all the terms in the lower order*)    (*a higher order contains all the terms in the lower order*) 

       t1=Sort[Expand[q7]];  t1=Sort[Expand[q7]];

       t2=Sort[AllTerms[ix,order-2]];  t2 = Sort[AllTerms[ix, order-2]];

       len1=Length[t1];  len1=Length[t1];

                                        Page29 Page29

                                       Slavin.txt  Slavin.txt

     len2=Length[t2];  len2=Length[t2];

     While[j2<=len1,  While[j2<=len1,

          If[t1[[j1]]==t2[[j2]],  If[t1[[j1]]==t2[[j2]],

             t1[[j1]]={};  t1[[j1]]={};

             If[j2==len2,  If[j2==len2,

                Break[];  Break[];

               ];  ];

             j2+=1;        j2+=1; 

            ];  ];

           j1+=1;       j1+=1; 

         ];  ];

       terms=Flatten[t1];  terms = Flatten[t1];

       ,  , ,

       terms=q7;  terms = q7;

      ];  ];

    len=Length[terms];  len=Length[terms];

    (*convert into form:Cos[(k*ix+m)*2*Pi*t/sx]*)  (*convert into form:Cos[(k*ix+m)*2*Pi*t/sx]*)

    cost=terms/.a_:>Cos[Apart[a*2*Pi*t/sx]];  Cost=terms/.a_:>Cos[Apart[a*2*Pi*t/sx]];

    (*find corresponding Sin[] terms*)  (*find corresponding Sin[] terms*)

    sint=cost/.Cos[a_]:>sin[a];  sint=cost/.Cos[a_]:>sin[a];

    (*expand general result for order*)  (*expand general result for order*)

    r0=product[Cos[2*Pi/sx(ix-1)(t-vars[[j+1+order]])]+  r0=product[Cos[2*Pi/sx(ix-1)(t-vars[[j+1+order]])]+

                vars[[j+1]]Cos[2*Pi/sx(ix+1)(t-vars[[j+1+order]])],  vars[[j+1]]Cos[2*Pi/sx(ix+1)(t-vars[[j+1+order]])],

                {j,1,order}];  {j,1,order}];

    r1=TrigReduce[r0];  r1=TrigReduce[r0];

    r2=r1/.Cos[a_]:>Cos[Collect[Together[a],t]];  r2=r1/.Cos[a_]:>Cos[Collect[Together[a],t]];

    r3=r2/.Cos[b_t+c_]->Cos[b*t]*Cos[c]-Sin[b*t]*Sin[c];  r3=r2/.Cos[b_t+c_]->Cos[b*t]*Cos[c]-Sin[b*t]*Sin[c];

    r4=r3/.{Cos[a_]:>Cos[Apart[a]],Sin[a_]:>Sin[Apart[a]]};  r4=r3/.{Cos[a_]:>Cos[Apart[a]], Sin[a_]:>Sin[Apart[a]]};

    r5=Table[{Coefficient[r4,cost[[j]]],Coefficient[r4,sint[[j]]]},  r5=Table[{Coefficient[r4, cost[[j]]], Coefficient[r4, sint[[j]]]},

               {j,1,len}];  {j,1,len}];

    Return[{terms,vars[[1]]*r5}];  Return[{terms, vars[[1]]*r5}];

  ]  ]

WfmColor[list_,color_]:=  WfmColor[list_, color_]:=

  Module[  Module[

      {max,r,g,b,data},  {max, r, g, b, data},

      r=color[[1]];  r = color[[1]];

      g=color[[2]];  g = color[[2]];

      b=color[[3]];  b = color[[3]];

      data=Transpose[list][[2]];  data = Transpose[list][[2]];

      max=Max[data];  max = Max[data];

      Return[ListPlot[list,{PlotJoined->True,  Return[ListPlot[list, {PlotJoined->True,

                             GridLines->Automatic,  GridLines->Automatic,

                             PlotRange->{max-150,max+5},  PlotRange->{max-150, max+5},

                             ImageSize->600,  ImageSize->600,

                             Plotstyle->RGBColor[r,g,b]}]];  Plotstyle->RGBColor[r,g,b]}]];

    ]  ]

EndPackage[]  EndPackage[]

                                     Page30 Page30

Claims (4)

1. calibration system comprises:
First analog signal generator produces first analog signal;
Second analog signal generator produces second analog signal;
Analog adder is connected to said first analog signal generator and said second analog signal generator, be used for said first analog signal and said second analog signal mutually adduction simulation output is provided;
ADC has the input and numeral output that are connected to said simulation output;
Linearity corrector with the input that is connected to said numeral output is realized the filter product is sued for peace;
Acquisition memory is connected to said numeral output; With
Processor is used to control said first analog signal generator and said second analog signal generator, is connected to read said acquisition memory data, also is connected to said linearity corrector so that be said filter product programming filter factor;
Wherein said first analog signal generator produces the primary sinusoid, and said second analog signal generator produces second sine wave; And
The wherein said primary sinusoid and said second sine wave have the frequency corresponding to the coprime multiple of the frequency of base data record length.
2. calibration system as claimed in claim 1; The rated frequency index wherein is provided; Said rated frequency index is the even multiple corresponding to the frequency of said base data record length; The said primary sinusoid subtracts one corresponding to said rated frequency index, and said second sine wave adds one corresponding to said rated frequency index.
3. calibration system as claimed in claim 1, wherein said processor comprises the special circuit that is used to seek the target function minimum value.
4. calibration system as claimed in claim 1, wherein said processor are that runs software program is to seek the general processor of target function minimum value.
CN 200510137332 2004-11-04 2005-11-04 Calibration system for a linearity corrector using filter products Expired - Fee Related CN1790916B (en)

Applications Claiming Priority (4)

Application Number Priority Date Filing Date Title
US62537204P 2004-11-04 2004-11-04
US60/625372 2004-11-04
US11/258237 2005-10-26
US11/258,237 US7161515B2 (en) 2004-11-04 2005-10-26 Calibration system and method for a linearity corrector using filter products

Related Child Applications (1)

Application Number Title Priority Date Filing Date
CN201210049028.5A Division CN102594346B (en) 2004-11-04 2005-11-04 Calibration system and method for a linearity corrector using filter products

Publications (2)

Publication Number Publication Date
CN1790916A CN1790916A (en) 2006-06-21
CN1790916B true CN1790916B (en) 2012-05-02

Family

ID=36788475

Family Applications (2)

Application Number Title Priority Date Filing Date
CN 200510131508 Expired - Fee Related CN1815893B (en) 2004-11-04 2005-11-04 Linearity corrector using filter products
CN 200510137332 Expired - Fee Related CN1790916B (en) 2004-11-04 2005-11-04 Calibration system for a linearity corrector using filter products

Family Applications Before (1)

Application Number Title Priority Date Filing Date
CN 200510131508 Expired - Fee Related CN1815893B (en) 2004-11-04 2005-11-04 Linearity corrector using filter products

Country Status (1)

Country Link
CN (2) CN1815893B (en)

Families Citing this family (10)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP5609684B2 (en) * 2011-02-01 2014-10-22 ソニー株式会社 AD converter and signal processing system
JP5733027B2 (en) * 2011-05-31 2015-06-10 ソニー株式会社 AD converter and signal processing system
CN104991119B (en) * 2015-07-01 2017-10-27 天津大学 A kind of coprime spectral analysis method and its device for eliminating pseudo- peak, composing leakage effect
CN105553904B (en) * 2015-12-09 2019-01-15 西安星通通信科技有限公司 A kind of digital signal amplitude and phase calibration method and system
CN105680859B (en) * 2016-01-29 2018-09-11 中国科学院微电子研究所 ADC built-in self-test circuit and test method in system on chip
KR102642577B1 (en) * 2016-12-12 2024-02-29 엘지디스플레이 주식회사 Driver Integrated Circuit For External Compensation And Display Device Including The Same And Data Calibration Method of The Display Device
CN114124037B (en) * 2020-08-25 2025-09-02 上海艾为电子技术股份有限公司 Signal processing device, electronic device, and signal processing method
CN114094973B (en) * 2020-08-25 2025-09-02 上海艾为电子技术股份有限公司 Signal processing device, electronic device, and signal processing method
WO2022076945A2 (en) * 2020-10-09 2022-04-14 That Corporation Genetic-algorithm-based equalization using iir filters
CN117155405B (en) * 2023-08-09 2024-07-12 海飞科(珠海)信息技术有限公司 Quick tANS coding and decoding conversion table establishment method based on gradient descent

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5594612A (en) * 1994-08-24 1997-01-14 Crystal Semiconductor Corporation Analog-to-digital converter with digital linearity correction
US6384757B1 (en) * 1999-09-20 2002-05-07 Nokia Networks Oy Method of calibrating an analog-to-digital converter, and a calibration equipment
US6639537B1 (en) * 2000-03-31 2003-10-28 Massachusetts Institute Of Technology Highly linear analog-to-digital conversion system and method thereof

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5594612A (en) * 1994-08-24 1997-01-14 Crystal Semiconductor Corporation Analog-to-digital converter with digital linearity correction
US6384757B1 (en) * 1999-09-20 2002-05-07 Nokia Networks Oy Method of calibrating an analog-to-digital converter, and a calibration equipment
US6639537B1 (en) * 2000-03-31 2003-10-28 Massachusetts Institute Of Technology Highly linear analog-to-digital conversion system and method thereof

Also Published As

Publication number Publication date
CN1815893B (en) 2012-04-18
CN1790916A (en) 2006-06-21
CN1815893A (en) 2006-08-09

Similar Documents

Publication Publication Date Title
CN101573592B (en) Compensate for Harmonic Distortion in Instrument Channels
JP4076553B2 (en) Calibration apparatus and linear corrector calibration method
US20130031442A1 (en) Multi-Dimensional Error Definition, Error Measurement, Error Analysis, Error Function Generation, Error Information Optimization, and Error Correction for Communications Systems
TWI423589B (en) Apparatus for and method of generating a sinusoidal signal and method of manufacturing a semiconductor device
US6911925B1 (en) Linearity compensation by harmonic cancellation
US7348908B2 (en) Linearity corrector using filter products
CN1790916B (en) Calibration system for a linearity corrector using filter products
US20080109503A1 (en) Sine wave generator with dual port look-up table
WO2004030219A1 (en) System and method for digital compensation of digital to analog and analog to digital converters
Yang et al. Minimax and WLS designs of digital FIR filters using SOCP for aliasing errors reduction in BI-DAC
Schmidt et al. Methodology and measurement setup for analog-to-digital converter postcompensation
Mikulik et al. Volterra filtering for integrating ADC error correction, based on an a priori error model
Kasher et al. Memory-efficient SFDR-optimized post-correction of analog-to-digital converters via frequency-selective look-up tables
Hu et al. The digital front end with dual-box digital pre-distortion in all-digital quadrature transmitter
EP1911162A1 (en) Method of and apparatus for characterising an analog to digital converter
Wang et al. Multiple Harmonics Fitting Algorithms Applied to Periodic Signals Based on Hilbert‐Huang Transform
Dubois et al. ADC low-complexity modelling identification and mitigation of baseband intermodulation distortion with instantaneous frequency dependence
Irons et al. Analog-to-digital converter error diagnosis
Leis Lock-in amplification based on sigma-delta oversampling
JP2004061415A (en) Method of testing characteristic of device
CN119291298A (en) A phase estimation method, signal processing channel and storage medium
Wu et al. Efficient algorithm for multi-tone spectral test of ADCs without requiring coherent sampling
US7206712B2 (en) Test apparatus and test method for mixed-signal semiconductor components
CN121049832A (en) An automatic compensation calibration method for energy meter measurement error
CN119414088A (en) A phase estimation method, signal processing channel and storage medium

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
CF01 Termination of patent right due to non-payment of annual fee

Granted publication date: 20120502

Termination date: 20191104

CF01 Termination of patent right due to non-payment of annual fee