# comm.gpu.PSKModulator

Modulate signals using M-PSK method with GPU

To use this object, you must install Parallel Computing Toolbox™ and have access to a supported GPU. If the host computer has a GPU configured, processing uses the GPU. Otherwise, processing uses the CPU. For more information about GPUs, see GPU Computing (Parallel Computing Toolbox).

## Description

The `comm.gpu.PSKModulator` object modulates a signal using the M-ary phase shift keying (M-PSK) method implemented on a graphics processing unit (GPU). The output is a baseband representation of the modulated signal.

To modulate a signal by using the M-PSK method:

1. Create the `comm.gpu.PSKModulator` object and set its properties.

2. Call the object with arguments, as if it were a function.

## Creation

### Syntax

``gpumpskmod = comm.gpu.PSKModulator``
``gpumpskmod = comm.gpu.PSKModulator(Name=Value)``
``gpumpskmod = comm.gpu.PSKModulator(M,Name=Value)``
``gpumpskmod = comm.gpu.PSKModulator(M,phase,Name=Value)``

### Description

````gpumpskmod = comm.gpu.PSKModulator` creates a GPU-based modulator System object™, that modulates the input signal using the M-PSK method.```
````gpumpskmod = comm.gpu.PSKModulator(Name=Value)` sets properties using one or more name-value arguments. For example, `comm.gpu.PSKModulator(BitInput=true)` specifies that input values must be binary.```

example

````gpumpskmod = comm.gpu.PSKModulator(M,Name=Value)` sets the `ModulationOrder` property to `M` and sets optional name-value arguments.```

example

````gpumpskmod = comm.gpu.PSKModulator(M,phase,Name=Value)` sets the `ModulationOrder` property to `M`, sets the `PhaseOffset` property to `phase`, and sets optional name-value arguments. Specify `phase` in radians.```

## Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the `release` function unlocks them.

If a property is tunable, you can change its value at any time.

Number of points in the signal constellation, specified as a positive integer.

Data Types: `double`

Phase of the zeroth point of the constellation in radians, specified as a scalar.

Example: `PhaseOffset=0` aligns the QPSK signal constellation points on the axes {(1,0), (0,j), (-1,0), (0,-j)}.

Data Types: `double`

Option to provide input in bits, specified as a numeric or logical `0` (`false`) or `1` (`true`).

• If you set this property to `false`, the input values must be integers in the range [`0`, (`ModulationOrder` – 1)].

• If you set this property to `true`, the input values must be binary and the input vector length must be an integer multiple of the number of bits per symbol, log2(`ModulationOrder`).

Data Types: `logical`

Symbol encoding mapping of the constellation bits, specified as `'Gray'`, `'Binary'`, or `'Custom'`. Each integer or group of log2(`ModulationOrder`) bits corresponds to one symbol.

• When you set this property to `'Gray'`, the object maps symbols to a Gray-encoded signal constellation.

• When you set this property to `'Binary'`, the object maps symbols to a natural binary-encoded signal constellation. Specifically, the complex value ej(`PhaseOffset` + (2πm/`ModulationOrder`)), where m is an integer in the range [`0`, (`ModulationOrder``1`)].

• When you set this property to `'Custom'`, the object maps symbols to the signal constellation defined in the `CustomSymbolMapping` property.

Custom symbol encoding, specified as an integer vector with length equal to the value of `ModulationOrder` and unique values in the range [`0`, (`ModulationOrder``1`)]. The first element of this vector corresponds to the constellation point at an angle of `0` + `PhaseOffset`, with subsequent elements running counterclockwise. The last element corresponds to the constellation point at an angle of –2π/`ModulationOrder` + `PhaseOffset`.

#### Dependencies

To enable this property, set the `SymbolMapping` property to `'Custom'`.

Data Types: `double`

Output data type, specified as either `'double'` or `'single'`.

## Usage

### Syntax

``y = gpumpskmod(x)``

### Description

````y = gpumpskmod(x)` modulates the input signal by using the M-PSK method. The output is the modulated M-PSK baseband signal.```

### Input Arguments

expand all

Input signal, specified as a column vector of integers or bits. The `BitInput` property specifies the expected input values and vector length.

To decrease data transfer latency, format the input signal as a `gpuArray` (Parallel Computing Toolbox) object. For more information, see Array Processing with GPU-Based System Objects.

Data Types: `double` | `single`

### Output Arguments

expand all

M-PSK modulated baseband signal, returned as a scalar or vector of complex-valued constellation symbols. The `OutputDataType` property specifies the data type of the output.

## Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named `obj`, use this syntax:

`release(obj)`

expand all

 `constellation` Calculate or plot ideal signal constellation
 `step` Run System object algorithm `release` Release resources and allow changes to System object property values and input characteristics `reset` Reset internal states of System object

## Examples

collapse all

Create binary data for 100, 4-bit symbols.

`data = randi([0 1],400,1);`

Create a 16-PSK modulator System object™ with bits as inputs and Gray-coded signal constellation. Change the phase offset to $\pi /16$.

```gpupskmod = comm.gpu.PSKModulator(16,'BitInput',true); gpupskmod.PhaseOffset = pi/16;```

Modulate and plot the data. Also, use the `constellation` object function to display the configured constellation.

```modData = gpupskmod(data); scatterplot(modData)```

`constellation(gpupskmod)`

In this example, you transmit 1/2 rate convolutionally encoded 16-PSK-modulated data through an AWGN channel, demodulate and decode the received data, and assess the error rate of the received data. For this implementation, you use the GPU-based Viterbi decoder System object™ to process multiple signal frames in a single call and then use `gpuArray` (Parallel Computing Toolbox) objects to pass data into and out of the GPU-based System objects.

Create GPU-based System objects for PSK modulation and demodulation, convolutional encoding, Viterbi decoding, and AWGN. Create a System object for error rate calculation.

```M = 16; % Modulation order numframes = 100; gpuconvenc = comm.gpu.ConvolutionalEncoder; gpupskmod = comm.gpu.PSKModulator(M,pi/16,BitInput=true); gpupskdemod = comm.gpu.PSKDemodulator(M,pi/16,BitOutput=true); gpuawgn = comm.gpu.AWGNChannel( ... NoiseMethod='Signal to noise ratio (SNR)',SNR=30); gpuvitdec = comm.gpu.ViterbiDecoder( ... InputFormat='Hard', ... TerminationMethod='Truncated', ... NumFrames=numframes); errorrate = comm.ErrorRate(ComputationDelay=0,ReceiveDelay=0);```

Due to the computational complexity of the Viterbi decoding algorithm, loading multiple frames of signal data on the GPU and processing them in one call can reduce overall simulation time. To enable this implementation, the GPU-based Viterbi decoder System object contains a `NumFrames` property. Instead of using an external `for`-loop to process individual frames of data, you use the `NumFrames` property to configure the GPU-based Viterbi decoder System object to process multiple data frames. Generate `numframes` of binary data frames. To efficiently manage the data frames for processing by the GPU-based System objects, represent the transmission data frames as a `gpuArray` object.

```numsymbols = 50; rate = 1/2; dataA = gpuArray.randi([0 1],rate*numsymbols*log2(M),numframes);```

The error rate object does not support `gpuArray` objects or multichannel data, so you must retrieve the array from the GPU by using the `gather` (Parallel Computing Toolbox) function to compute the error rate on each frame of data in a `for`-loop. Perform the GPU-based encoding, modulation, AWGN, and demodulation inside a `for`-loop.

```for ii = 1:numframes encodedData = gpuconvenc(dataA(:,ii)); modsig = gpupskmod(encodedData); noisysig = gpuawgn(modsig); demodsig(:,ii) = gpupskdemod(noisysig); end```

The GPU-based Viterbi decoder performs multiframe processing without a `for`-loop.

```rxbits = gpuvitdec(demodsig(:)); errorStats = errorrate(gather(dataA(:)),gather(rxbits)); fprintf('BER = %f\nNumber of errors = %d\nTotal bits = %d', ... errorStats(1), errorStats(2), errorStats(3))```
```BER = 0.009800 Number of errors = 98 Total bits = 10000 ```

expand all

## Algorithms

For binary-encoding, the output baseband signal maps input bits or integers to complex symbols according to:

`${s}_{n}\left(t\right)=\mathrm{exp}\left(j\pi \left(\frac{2n+1}{M}\right)\right);\text{ }n\in \left\{0,1,\dots ,M-1\right\}.$`

When the input is configured for bits, groups of log2(M) bits represent the complex symbols for the configured symbol mapping. The mapping can be binary encoded, Gray encoded, or custom encoded.

Gray coding has the advantage that only one bit changes between adjacent constellation points, which results in better bit error rate performance. This table shows the mapping between the input and output symbols for 8-PSK modulation with Gray coding.

InputOutput
0 0 (000)
1 1 (001)
2 3 (011)
3 2 (010)
4 6 (110)
5 7 (111)
6 5 (101)
7 4 (100)

This constellation diagram shows the corresponding symbols and their binary values.

## References

[1] Proakis, John G. Digital Communications. 4th ed. New York: McGraw Hill, 2001.

## Version History

Introduced in R2012a