# comm.EVM

Measure error vector magnitude

## Description

The `comm.EVM` (error vector magnitude) System object™ measures the modulator or demodulator performance of an impaired signal.

To measure error vector magnitude:

1. Define and set up your EVM object. See Construction.

2. Call `step` to measure the modulator or demodulator performance according to the properties of `comm.EVM`. The behavior of `step` is specific to each object in the toolbox.

Note

Starting in R2016b, instead of using the `step` method to perform the operation defined by the System object, you can call the object with arguments, as if it were a function. For example, ```y = step(obj,x)``` and `y = obj(x)` perform equivalent operations.

## Construction

`EVM = comm.EVM` creates an error vector magnitude object, `EVM`. This object measures the amount of impairment in a modulated signal.

`EVM = comm.EVM(Name,Value)` creates an `EVM` object with each specified property set to the specified value. You can specify additional name-value pair arguments in any order as (`Name1`,`Value1`,...,`NameN`,`ValueN`).

Example: ```EVM = comm.EVM('ReferenceSignalSource','Estimated from reference constellation')``` creates an object, `EVM`, that measures the RMS EVM of a received signal by using a reference constellation.

## Properties

 `Normalization` Normalization method Normalization method used in EVM calculation, specified as one of the following: `'Average reference signal power'` (default), ```'Average constellation power'```, or `'Peak constellation power'`. `AverageConstellationPower` Average constellation power Average constellation power, specified in watts as a positive real scalar. This property is available when `Normalization` is ```'Average constellation power'```. The default is `1`. `PeakConstellationPower` Peak constellation power Peak constellation power, specified in watts as a positive real scalar. This property is available when `Normalization` is ```'Peak constellation power'```. The default is `1`. `ReferenceSignalSource` Reference signal source Reference signal source, specified as either ```'Input port'``` (default) or `'Estimated from reference constellation'`. To provide an explicit reference signal against which the input signal is measured, set this property to `'Input port'`. To measure the EVM of the input signal against a reference constellation, set this property to `'Estimated from reference constellation'`. `ReferenceConstellation` Reference constellation Reference constellation, specified as a vector. This property is available when the `ReferenceSignalSource` property is `'Estimated from reference constellation'`. The default is ```[0.7071 - 0.7071i; -0.7071 - 0.7071i; -0.7071 + 0.7071i; 0.7071 + 0.7071i]```, which corresponds to a standard QPSK constellation. You can derive constellation points by using modulation functions or objects. For example, to derive the reference constellation for a 16-QAM signal, you can use `qammod(0:15,16)`. `MeasurementIntervalSource` Measurement interval source Measurement interval source, specified as one of the following: ```'Input length'``` (default), `'Entire history'`, `'Custom'`, or `'Custom with periodic reset'`. This property affects the RMS and maximum EVM outputs only. To calculate EVM using only the current samples, set this property to `'Input length'`.To calculate EVM for all samples, set this property to `'Entire history'`.To calculate EVM over an interval you specify and to use a sliding window, set this property to `'Custom'`.To calculate EVM over an interval you specify and to reset the object each time the measurement interval is filled, set this property to `'Custom with periodic reset'`. `MeasurementInterval` Measurement interval Measurement interval over which the EVM is calculated, specified in samples as a real positive integer. This property is available when `MeasurementIntervalSource` is `'Custom'` or ```'Custom with periodic reset'```. The default is `100`. `AveragingDimensions` Averaging dimensions Averaging dimensions over which to average the EVM measurements, specified as an integer or row vector of integers with element values in the range [1, 3]. For example, to average across the rows, set this property to `2`. The default is `1`. The object supports variable-size inputs over the dimensions in which the averaging takes place. However, the input size for the nonaveraged dimensions must remain constant between calls of the object. For example, if the input has size `[4 3 2]` and `Averaging dimensions` is `[1 3]`, the output size is `[1 3 1]`, and the second dimension must remain fixed at `3`. `MaximumEVMOutputPort` Maximum EVM measurement output port Maximum EVM measurement output port, specified as a logical scalar. To create an output port for maximum EVM measurements, set this property to `true`. The default is `false`. `XPercentileEVMOutputPort` X-percentile EVM measurement output port X-percentile EVM measurement output port, specified as a logical scalar. To create an output port for X-percentile EVM measurements, set this property to `true`. The X-percentile EVM measurements persist until you reset the object. These measurements are calculated by using all of the input frames since the last reset. The default is `false`. `XPercentileValue` X-percentile value X-percentile value below which X% of the EVM measurements fall, specified as a real scalar from `0` to `100`. This property is available when `XPercentileEVMOutputPort` is `true`. The default is `95`. `SymbolCountOutputPort` Symbol count output port Symbol count output port, specified as a logical scalar. To output the number of accumulated symbols used to calculate the X-percentile EVM measurements, set this property to `true`. This property is available when `XPercentileEVMOutputPort` is `true`. The default is `false`.

## Methods

 reset Reset states of EVM measurement object step Measure error vector magnitude
Common to All System Objects
`release`

Allow System object property value changes

## Examples

collapse all

Create an EVM object. Configure it using name-value pairs to output maximum EVM, 90th percentile EVM, and the symbol count.

```evm = comm.EVM('MaximumEVMOutputPort',true,... 'XPercentileEVMOutputPort',true, 'XPercentileValue',90,... 'SymbolCountOutputPort',true);```

Generate random data symbols. Apply 16-QAM modulation. The modulated signal serves as the reference for the subsequent EVM measurements.

```data = randi([0 15],1000,1); refSym = qammod(data,16,'UnitAveragePower',true);```

Pass the modulated signal through an AWGN channel.

`rxSym = awgn(refSym,20);`

Measure the EVM of the noisy signal.

`[rmsEVM,maxEVM,pctEVM,numSym] = evm(refSym,rxSym)`
```rmsEVM = 9.8775 ```
```maxEVM = 26.8385 ```
```pctEVM = 14.9750 ```
```numSym = 1000 ```

Generate filtered QAM data and pass it through an AWGN channel. Compute the symbol error rate, and estimate the EVM of the received signal.

Create channel and filter System objects™.

```M = 16; refConst = qammod(0:M-1,M); channel = comm.AWGNChannel('NoiseMethod','Signal to noise ratio (SNR)',... 'SNR',15,'SignalPower',10); txfilter = comm.RaisedCosineTransmitFilter('OutputSamplesPerSymbol',4); rxfilter = comm.RaisedCosineReceiveFilter('InputSamplesPerSymbol',4, ... 'DecimationFactor',4);```

Create an EVM object to output RMS and maximum EVM measurements.

```evm = comm.EVM('MaximumEVMOutputPort',true, ... 'ReferenceSignalSource','Estimated from reference constellation', ... 'ReferenceConstellation',refConst);```

Create an error rate object and account for the signal delay through the transmit and receive filters. For a filter, the group delay is equal to 1/2 of the `FilterSpanInSymbols` property.

```rxd = (txfilter.FilterSpanInSymbols + rxfilter.FilterSpanInSymbols)/2; errorRate = comm.ErrorRate('ReceiveDelay',rxd);```

Perform the following channel operations:

• Generate random data symbols.

• Apply 16-QAM modulation.

• Filter the modulated data through a raised cosine Tx filter.

• Pass the transmitted signal through an AWGN channel.

• Filter the received data through a raised cosine Rx filter.

• Demodulate the filtered data.

```txData = randi([0 15],1000,1); modData = qammod(txData,M); txSig = txfilter(modData); rxSig = channel(txSig); filtSig = rxfilter(rxSig); rxData = qamdemod(filtSig,M);```

Calculate the error statistics and display the symbol error rate.

```errStats = errorRate(txData,rxData); symErrRate = errStats(1)```
```symErrRate = 0.0222 ```

Measure and display the received RMS EVM and maximum EVM values. Take the filter delay into account by deleting the first `rxd+1` symbols. Because there are symbol errors, the EVM may not be totally accurate.

`[rmsEVM,maxEVM] = evm(filtSig(rxd+1:end))`
```rmsEVM = 17.2966 ```
```maxEVM = 40.1595 ```

Generate random data symbols, and apply 8-PSK modulation.

```d = randi([0 7],2000,1); txSig = pskmod(d,8,pi/8);```

Pass the modulated signal through an AWGN channel.

`rxSig = awgn(txSig,30);`

Create an EVM object. Measure the RMS EVM using the transmitted signal as the reference.

```evm = comm.EVM; rmsEVM1 = evm(txSig,rxSig);```

Release the EVM object. Configure the object to estimate the EVM of the received signal against a reference constellation.

```release(evm) evm.ReferenceSignalSource = 'Estimated from reference constellation'; evm.ReferenceConstellation = pskmod(0:7,8,pi/8);```

Measure the RMS EVM using only the received signal as an input. Verify that it matches the result obtained when using a reference signal.

```rmsEVM2 = evm(rxSig); [rmsEVM1 rmsEVM2]```
```ans = 1×2 3.1524 3.1524 ```

Measure the EVM of a noisy 8-PSK signal using two types of custom measurement intervals. Display the results.

Set the number of frames, `M`, and the number of subframes per frame, `K`.

```M = 2; K = 5;```

Set the number of symbols in a subframe. Calculate the corresponding frame length.

```sfLen = 100; frmLen = K*sfLen```
```frmLen = 500 ```

Create an EVM object. Configure the object to use a custom measurement interval equal to the frame length.

```evm1 = comm.EVM('MeasurementIntervalSource','Custom', ... 'MeasurementInterval',frmLen);```

Configure the object to measure EVM using an 8-PSK reference constellation.

```evm1.ReferenceSignalSource = 'Estimated from reference constellation'; evm1.ReferenceConstellation = pskmod(0:7,8,pi/8);```

Create an EVM object, and configure it use a 500-symbol measurement interval with a periodic reset. Configure the object to measure EVM using an 8-PSK reference constellation.

```evm2 = comm.EVM('MeasurementIntervalSource','Custom with periodic reset', ... 'MeasurementInterval',frmLen); evm2.ReferenceSignalSource = 'Estimated from reference constellation'; evm2.ReferenceConstellation = pskmod(0:7,8,pi/8);```

Initialize the EVM and signal-to-noise arrays.

```rmsEVM1 = zeros(K,M); rmsEVM2 = zeros(K,M); snrdB = zeros(K,M);```

Measure the EVM for a noisy 8-PSK signal using both objects. The SNR increases by 1 dB from subframe to subframe. For `evm1`, the 500 most recent symbols are used to compute the estimate. In this case, a sliding window is used so that an entire frame of data is always processed. For `evm2`, the symbols are cleared each time a new frame is encountered.

```for m = 1:M for k = 1:K data = randi([0 7],sfLen,1); txSig = pskmod(data,8,pi/8); snrdB(k,m) = k+(m-1)*K+7; rxSig = awgn(txSig,snrdB(k,m)); rmsEVM1(k,m) = evm1(rxSig); rmsEVM2(k,m) = evm2(rxSig); end end```

Display the EVM measured using the two approaches. The windowing used in the first case provides an averaging across the subframes. In the second case, the EVM object resets after the first frame so that the calculated EVM values more accurately reflect the current SNR.

```stairs(snrdB(:),[rmsEVM1(:) rmsEVM2(:)]) xlabel('SNR (dB)') ylabel('EVM (%)') legend('No Reset','Periodic Reset')```

Create OFDM modulator and demodulator objects.

```ofdmmod = comm.OFDMModulator('FFTLength',32,'NumSymbols',4); ofdmdemod = comm.OFDMDemodulator('FFTLength',32,'NumSymbols',4);```

Determine the number of subcarriers and symbols in the OFDM signal.

```ofdmDims = info(ofdmmod); numSC = ofdmDims.DataInputSize(1)```
```numSC = 21 ```
`numSym = ofdmDims.DataInputSize(2)`
```numSym = 4 ```

Generate random symbols and apply QPSK modulation.

```msg = randi([0 3],numSC,numSym); modSig = pskmod(msg,4,pi/4);```

OFDM modulate the QPSK signal. Pass the signal through an AWGN channel. Demodulate the noisy signal.

```txSig = ofdmmod(modSig); rxSig = awgn(txSig,10,'measured'); demodSig = ofdmdemod(rxSig);```

Create an EVM object, where the result is averaged over the subcarriers. Measure the EVM. There are four entries corresponding to each of the 4 OFDM symbols.

```evm = comm.EVM('AveragingDimensions',1); rmsEVM = evm(demodSig,modSig)```
```rmsEVM = 1×4 27.4354 23.6279 22.6772 23.1699 ```

Overwrite the EVM object, where the result is averaged over the OFDM symbols. Measure the EVM. There are 21 entries corresponding to each of the 21 subcarriers.

```evm = comm.EVM('AveragingDimensions',2); rmsEVM = evm(demodSig,modSig)```
```rmsEVM = 21×1 28.8225 17.8536 18.6809 20.8872 22.3532 24.7197 30.1954 33.4899 36.2847 21.4230 ⋮ ```

Measure the EVM and average over both the subcarriers and the OFDM symbols.

```evm = comm.EVM('AveragingDimensions',[1 2]); rmsEVM = evm(demodSig,modSig)```
```rmsEVM = 24.2986 ```

Calculate and plot the EVM of an OFDM signal. The signal consists of two packets separated by an interval.

Create System objects to:

• OFDM modulate a signal

• Introduce phase noise

• Plot time-varying signals

```ofdmmod = comm.OFDMModulator('FFTLength',256,'NumSymbols',2); pnoise = comm.PhaseNoise('Level',-60,'FrequencyOffset',20,'SampleRate',1000); tscope = timescope('YLabel','EVM (%)','YLimits',[0 40], ... 'SampleRate',1000,'TimeSpanSource','Property','TimeSpan',1.2, ... 'ShowGrid',true); ```

Create an EVM object. To generate a time-varying estimate of the EVM, set the `AveragingDimensions` property to `2`.

```evm = comm.EVM('MaximumEVMOutputPort',false, ... 'ReferenceSignalSource','Input port', ... 'AveragingDimensions',2); ```

Determine the input data dimensions of the OFDM modulator.

```modDims = info(ofdmmod) ```
```modDims = struct with fields: DataInputSize: [245 2] OutputSize: [544 1] ```

Create QPSK-modulated random data for the first packet. Apply OFDM modulation.

```data = randi([0 3],modDims.DataInputSize); qpskSig = pskmod(data,4,pi/4); txSig1 = ofdmmod(qpskSig); ```

Create a second data packet.

```data = randi([0 3],modDims.DataInputSize); qpskSig = pskmod(data,4,pi/4); txSig2 = ofdmmod(qpskSig); ```

Concatenate the two packets and include an interval in which nothing is transmitted.

```txSig = [txSig1; zeros(112,1); txSig2]; ```

Apply I/Q amplitude and phase imbalance to the transmitted signal.

```rxSigIQimb = iqimbal(txSig,2,5); ```

Apply phase noise.

```rxSig = pnoise(rxSigIQimb); ```

Measure the EVM of the received signal, and plot its time-varying EVM.

```e = evm(txSig,rxSig); tscope(e) ```

## Algorithms

Both the EVM block and the EVM object provide three normalization methods. You can normalize measurements according to the average power of the reference signal, average constellation power, or peak constellation power. Different industry standards follow one of these normalization methods.

The block or object calculates the RMS EVM value differently for each normalization method.

EVM Normalization MethodAlgorithm
Reference signal

`$EV{M}_{RMS}=\sqrt{\frac{\frac{1}{N}\sum _{k=1}^{N}\left({e}_{k}\right)}{\frac{1}{N}\sum _{k=1}^{N}\left({I}_{k}^{2}+{Q}_{k}^{2}\right)}}*100$`

Average power

`${\text{EVM}}_{\text{RMS}}\left(\text{%}\right)=100\sqrt{\frac{\frac{1}{N}\sum _{k=1}^{N}\left({e}_{k}\right)}{{P}_{\text{avg}}}}$`

Peak power

`${\text{EVM}}_{\text{RMS}}\left(\text{%}\right)=100\sqrt{\frac{\frac{1}{N}\sum _{k=1}^{N}\left({e}_{k}\right)}{{P}_{\text{max}}}}$`

Where:

• ek = ${e}_{k}={\left({I}_{k}-{\stackrel{˜}{I}}_{k}\right)}^{2}+{\left({Q}_{k}-{\stackrel{˜}{Q}}_{k}\right)}^{2}$

• Ik = In-phase measurement of the kth symbol in the burst

• Qk = Quadrature phase measurement of the kth symbol in the burst

• N = Input vector length

• Pavg = The value for Average constellation power

• Pmax = The value for Peak constellation power

• Ik and Qk represent ideal (reference) values. ${\stackrel{˜}{I}}_{k}$ and ${\stackrel{˜}{Q}}_{k}$ represent measured (received) symbols.

The max EVM is the maximum EVM value in a frame or ${\text{EVM}}_{\text{max}}=\underset{k\in \left[1,...,N\right]}{\text{max}}\left\{{\text{EVM}}_{k}\right\}\text{\hspace{0.17em}}\text{,}$ where k is the kth symbol in a burst of length N.

The definition for EVMk varies depending upon which normalization method you select for computing measurements. The block or object supports these algorithms.

EVM NormalizationAlgorithm
Reference signal

`$EV{M}_{k}=\sqrt{\frac{{e}_{k}}{\frac{1}{N}\sum _{k=1}^{N}\left({I}_{k}^{2}+{Q}_{k}^{2}\right)}}*\text{​}100$`

Average power

`${\text{EVM}}_{k}=100\sqrt{\frac{{e}_{k}}{{P}_{\text{avg}}}}$`

Peak power

`${\text{EVM}}_{k}=100\sqrt{\frac{{e}_{k}}{{P}_{\text{max}}}}$`

The block or object computes the X-percentile EVM by creating a histogram of all the incoming EVMk values. The output provides the EVM value below which X% of the EVM values fall.