Merge branch 'main' of cau-git.rz.uni-kiel.de:nt/mitarbeiter/silas/imdd_simulation
This commit is contained in:
344
AGENT_OVERVIEW.md
Normal file
344
AGENT_OVERVIEW.md
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
# IM/DD Simulation Framework Overview
|
||||||
|
|
||||||
|
This file is for agents that encounter this repository for the first time.
|
||||||
|
Its goal is to explain what the codebase is for, where the main building
|
||||||
|
blocks live, and how a typical IM/DD workflow is assembled.
|
||||||
|
|
||||||
|
It is not a testing guide. The focus here is the simulation framework itself.
|
||||||
|
|
||||||
|
## What This Repository Is
|
||||||
|
|
||||||
|
This repository is a MATLAB-based simulation and analysis framework for
|
||||||
|
IM/DD optical communication systems.
|
||||||
|
|
||||||
|
At a high level, the codebase supports:
|
||||||
|
|
||||||
|
- generation of digital symbol and bit streams
|
||||||
|
- electrical transmitter modeling
|
||||||
|
- electro-optical modulation
|
||||||
|
- optical channel modeling
|
||||||
|
- photodetection and receiver front-end processing
|
||||||
|
- digital signal processing and sequence detection
|
||||||
|
- metric evaluation such as BER, GMI, AIR, EVM, and SNR
|
||||||
|
- project-specific simulation scripts and experimental analysis workflows
|
||||||
|
|
||||||
|
The codebase is not just one monolithic simulator. It is a toolkit of
|
||||||
|
reusable classes plus many project scripts that assemble those classes in
|
||||||
|
different ways.
|
||||||
|
|
||||||
|
## Mental Model
|
||||||
|
|
||||||
|
The easiest way to understand the repository is as a staged signal chain:
|
||||||
|
|
||||||
|
1. Information signal generation
|
||||||
|
2. Symbol mapping and pulse shaping
|
||||||
|
3. AWG / electrical drive path
|
||||||
|
4. Optical modulation
|
||||||
|
5. Fiber / channel propagation
|
||||||
|
6. Receiver front-end
|
||||||
|
7. Synchronization and DSP
|
||||||
|
8. Performance evaluation
|
||||||
|
|
||||||
|
The classes in `Classes/` implement the reusable blocks.
|
||||||
|
The scripts in `projects/` wire those blocks together into concrete systems.
|
||||||
|
|
||||||
|
## Suggested First File To Read
|
||||||
|
|
||||||
|
For a compact end-to-end example, start here:
|
||||||
|
|
||||||
|
- `projects/IMDD_base_system/minimal_example.m`
|
||||||
|
|
||||||
|
That file shows a reduced but representative full workflow:
|
||||||
|
|
||||||
|
- `PAMsource`
|
||||||
|
- `AWG`
|
||||||
|
- `EML`
|
||||||
|
- `Fiber`
|
||||||
|
- `Amplifier`
|
||||||
|
- `Photodiode`
|
||||||
|
- `Filter`
|
||||||
|
- `Scope`
|
||||||
|
- matched filtering
|
||||||
|
- synchronization
|
||||||
|
- equalization / MLSE
|
||||||
|
|
||||||
|
If you need to understand “how the system is intended to be used”, this is
|
||||||
|
one of the best entry points.
|
||||||
|
|
||||||
|
## Top-Level Structure
|
||||||
|
|
||||||
|
### `Classes/`
|
||||||
|
|
||||||
|
This is the core reusable framework.
|
||||||
|
Most simulation building blocks live here.
|
||||||
|
|
||||||
|
Subfolders are organized by role:
|
||||||
|
|
||||||
|
- `00_signals`
|
||||||
|
Base signal classes and core signal behavior.
|
||||||
|
This is the semantic foundation used by most of the rest of the codebase.
|
||||||
|
|
||||||
|
- `01_transmit`
|
||||||
|
Digital TX-side blocks such as bit/symbol generation, mapping, pulse
|
||||||
|
shaping, and AWG-related functionality.
|
||||||
|
|
||||||
|
- `02_etc`
|
||||||
|
General-purpose support blocks, especially filtering and amplification.
|
||||||
|
|
||||||
|
- `02_optical`
|
||||||
|
Optical-domain components such as modulators, multiplexing, fiber/channel
|
||||||
|
propagation, and related physical effects.
|
||||||
|
|
||||||
|
- `03_electrical`
|
||||||
|
Electrical-domain helper blocks and traces.
|
||||||
|
|
||||||
|
- `03_receive`
|
||||||
|
RX-side front-end blocks such as photodiodes and scopes/ADC behavior.
|
||||||
|
|
||||||
|
- `04_DSP`
|
||||||
|
Equalizers, timing recovery, postfilters, coding blocks, and sequence
|
||||||
|
detection such as MLSE.
|
||||||
|
|
||||||
|
- `05_Lab`
|
||||||
|
Instrument-control classes for real hardware.
|
||||||
|
These are not just simulations. They can talk to reachable devices.
|
||||||
|
|
||||||
|
- `DataBaseHandler`
|
||||||
|
Query/filter/result structures and database-facing helper classes.
|
||||||
|
|
||||||
|
- `Warehouse_class`
|
||||||
|
More specialized storage / plotting / result-handling infrastructure.
|
||||||
|
|
||||||
|
### `Functions/`
|
||||||
|
|
||||||
|
This holds free functions and workflow helpers that are not packaged as
|
||||||
|
classes.
|
||||||
|
|
||||||
|
Important subareas:
|
||||||
|
|
||||||
|
- `EQ_structures`
|
||||||
|
Higher-level DSP driver functions such as `ffe`, `vnle_postfilter_mlse`,
|
||||||
|
and related end-stage evaluation helpers.
|
||||||
|
|
||||||
|
- `Metrics`
|
||||||
|
BER, EVM, GMI, AIR, SNR, and related performance calculations.
|
||||||
|
|
||||||
|
- `EQ_visuals`
|
||||||
|
Diagnostic and visualization helpers for equalizers and result analysis.
|
||||||
|
|
||||||
|
- `channel_structures`
|
||||||
|
Channel-model helpers.
|
||||||
|
|
||||||
|
- `Job_Processing`
|
||||||
|
Scriptable processing helpers for bigger job/result workflows.
|
||||||
|
|
||||||
|
- `Theory`
|
||||||
|
Supporting theory calculations and one-off analytic utilities.
|
||||||
|
|
||||||
|
### `Datatypes/`
|
||||||
|
|
||||||
|
This contains enums and small type definitions used throughout the codebase.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- normalization modes
|
||||||
|
- power notation
|
||||||
|
- filter types
|
||||||
|
- modulation / adaptation enums
|
||||||
|
|
||||||
|
When a class constructor takes a symbolic mode value, it is often defined here.
|
||||||
|
|
||||||
|
### `projects/`
|
||||||
|
|
||||||
|
This is where the reusable framework gets turned into concrete systems,
|
||||||
|
experiments, and studies.
|
||||||
|
|
||||||
|
The `projects/` folder is broad and includes:
|
||||||
|
|
||||||
|
- minimal examples
|
||||||
|
- paper-specific studies
|
||||||
|
- lab analysis scripts
|
||||||
|
- offline DSP pipelines
|
||||||
|
- experiment-specific workflows
|
||||||
|
|
||||||
|
These scripts are often the best place to understand intended usage patterns.
|
||||||
|
|
||||||
|
### `Tests/`
|
||||||
|
|
||||||
|
This contains the current MATLAB unit/integration test framework.
|
||||||
|
It validates parts of the reusable framework, not the full meaning of the
|
||||||
|
repository.
|
||||||
|
|
||||||
|
Use it as a quality tool, not as the primary documentation source for what
|
||||||
|
the simulation does.
|
||||||
|
|
||||||
|
## Core Signal Classes
|
||||||
|
|
||||||
|
The repository uses class-based signal objects instead of raw arrays whenever
|
||||||
|
possible.
|
||||||
|
|
||||||
|
Key signal classes:
|
||||||
|
|
||||||
|
- `Signal`
|
||||||
|
Base class with common signal behavior, metadata, logbook, arithmetic,
|
||||||
|
normalization, resampling, plotting, and utility methods.
|
||||||
|
|
||||||
|
- `Informationsignal`
|
||||||
|
Discrete/digital information-level representation.
|
||||||
|
|
||||||
|
- `Electricalsignal`
|
||||||
|
Electrical-domain signal representation.
|
||||||
|
|
||||||
|
- `Opticalsignal`
|
||||||
|
Optical-domain signal representation including optical metadata such as
|
||||||
|
wavelength and ASE-related quantities.
|
||||||
|
|
||||||
|
These classes are central because many other blocks accept or return them.
|
||||||
|
|
||||||
|
## Typical Workflow Composition
|
||||||
|
|
||||||
|
A representative IM/DD chain often looks like this:
|
||||||
|
|
||||||
|
1. `PAMsource`
|
||||||
|
Creates bits, mapped symbols, and shaped digital transmit signals.
|
||||||
|
|
||||||
|
2. `AWG`
|
||||||
|
Applies DAC-like processing, upsampling, quantization, and optional
|
||||||
|
filtering.
|
||||||
|
|
||||||
|
3. `EML`
|
||||||
|
Converts the electrical drive signal to an optical signal.
|
||||||
|
|
||||||
|
4. `Fiber`
|
||||||
|
Applies optical channel propagation.
|
||||||
|
|
||||||
|
5. `Amplifier`
|
||||||
|
Sets optical power / gain and can manipulate ASE handling.
|
||||||
|
|
||||||
|
6. `Photodiode`
|
||||||
|
Performs square-law detection and creates an electrical RX signal.
|
||||||
|
|
||||||
|
7. `Filter`
|
||||||
|
Applies electrical filtering.
|
||||||
|
|
||||||
|
8. `Scope`
|
||||||
|
Models ADC / sampling / quantization / optional RX-side LPF behavior.
|
||||||
|
|
||||||
|
9. `Pulseformer` in matched-filter mode
|
||||||
|
Used again on the RX side as matched filtering.
|
||||||
|
|
||||||
|
10. `tsynch`
|
||||||
|
Synchronizes the RX signal against transmitted symbols.
|
||||||
|
|
||||||
|
11. DSP blocks
|
||||||
|
Examples:
|
||||||
|
- `FFE`
|
||||||
|
- `EQ`
|
||||||
|
- `Postfilter`
|
||||||
|
- `MLSE`
|
||||||
|
- timing-recovery variants
|
||||||
|
|
||||||
|
12. Metrics
|
||||||
|
Performance is evaluated via helper functions and result structures.
|
||||||
|
|
||||||
|
## Two Important Layers
|
||||||
|
|
||||||
|
There are two distinct abstraction levels in the repo:
|
||||||
|
|
||||||
|
### 1. Block-level classes
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `PAMsource`
|
||||||
|
- `Pulseformer`
|
||||||
|
- `AWG`
|
||||||
|
- `EML`
|
||||||
|
- `Fiber`
|
||||||
|
- `Photodiode`
|
||||||
|
- `Scope`
|
||||||
|
- `FFE`
|
||||||
|
- `MLSE`
|
||||||
|
|
||||||
|
These are the reusable simulation primitives.
|
||||||
|
|
||||||
|
### 2. Workflow-level functions/scripts
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- `projects/.../minimal_example.m`
|
||||||
|
- `Functions/EQ_structures/ffe.m`
|
||||||
|
- `Functions/EQ_structures/vnle_postfilter_mlse.m`
|
||||||
|
|
||||||
|
These assemble the primitives into practical runs and performance outputs.
|
||||||
|
|
||||||
|
When debugging behavior, it matters which layer you are in:
|
||||||
|
|
||||||
|
- if a signal object has the wrong shape or `fs`, look at block-level classes
|
||||||
|
- if BER/GMI pipelines behave unexpectedly, also inspect workflow-level DSP helpers
|
||||||
|
|
||||||
|
## Where To Look For What
|
||||||
|
|
||||||
|
If you want to understand:
|
||||||
|
|
||||||
|
- base signal semantics:
|
||||||
|
read `Classes/00_signals/*`
|
||||||
|
|
||||||
|
- transmitter generation:
|
||||||
|
read `Classes/01_transmit/*`
|
||||||
|
|
||||||
|
- optical propagation:
|
||||||
|
read `Classes/02_optical/*`
|
||||||
|
|
||||||
|
- receiver modeling:
|
||||||
|
read `Classes/03_receive/*`
|
||||||
|
|
||||||
|
- equalization and detection:
|
||||||
|
read `Classes/04_DSP/*` and `Functions/EQ_structures/*`
|
||||||
|
|
||||||
|
- metric definitions:
|
||||||
|
read `Functions/Metrics/*`
|
||||||
|
|
||||||
|
- intended end-to-end usage:
|
||||||
|
read `projects/IMDD_base_system/minimal_example.m`
|
||||||
|
|
||||||
|
## How To Approach The Repo As A New Agent
|
||||||
|
|
||||||
|
A good first-pass reading order is:
|
||||||
|
|
||||||
|
1. `projects/IMDD_base_system/minimal_example.m`
|
||||||
|
2. `Classes/00_signals/Signal.m`
|
||||||
|
3. `Classes/01_transmit/PAMsource.m`
|
||||||
|
4. `Classes/01_transmit/Pulseformer.m`
|
||||||
|
5. `Classes/01_transmit/AWG.m`
|
||||||
|
6. `Classes/02_optical/EML.m`
|
||||||
|
7. `Classes/02_optical/Fiber.m`
|
||||||
|
8. `Classes/03_receive/Photodiode.m`
|
||||||
|
9. `Classes/03_receive/Scope.m`
|
||||||
|
10. `Functions/EQ_structures/ffe.m`
|
||||||
|
11. `Functions/EQ_structures/vnle_postfilter_mlse.m`
|
||||||
|
12. `Classes/04_DSP/Equalizer/FFE.m`
|
||||||
|
13. `Classes/04_DSP/Sequence Detection/MLSE.m`
|
||||||
|
|
||||||
|
This gives both the architectural view and the runtime path.
|
||||||
|
|
||||||
|
## Practical Safety Note
|
||||||
|
|
||||||
|
Do not casually execute or test `Classes/05_Lab/*`.
|
||||||
|
|
||||||
|
Those are lab-device control classes, not harmless simulations.
|
||||||
|
In this environment, reachable device IPs can exist, and executing those
|
||||||
|
classes may change instrument set points and interfere with active experiments.
|
||||||
|
|
||||||
|
Treat `05_Lab` as operational code, not as a normal simulation subfolder.
|
||||||
|
|
||||||
|
## Final Summary
|
||||||
|
|
||||||
|
The repository is best understood as:
|
||||||
|
|
||||||
|
- a reusable class library for IM/DD system building blocks
|
||||||
|
- plus workflow helpers for DSP and analysis
|
||||||
|
- plus many project scripts that instantiate those blocks for concrete studies
|
||||||
|
|
||||||
|
If you are lost, do not start from `Tests/`.
|
||||||
|
Start from the minimal project workflow, then map each stage back to the
|
||||||
|
relevant class folder in `Classes/`.
|
||||||
@@ -1,135 +1,3 @@
|
|||||||
|
|
||||||
% plot_dispersion_models
|
|
||||||
% ------------------------------------------------------------
|
|
||||||
% Visualizes exact and linearized chromatic dispersion D(λ)
|
|
||||||
% around the zero-dispersion wavelength (ZDW).
|
|
||||||
%
|
|
||||||
% Inputs:
|
|
||||||
% lambda0_nm - ZDW in nm
|
|
||||||
% S0 - dispersion slope at ZDW [ps/(nm^2·km)]
|
|
||||||
% ------------------------------------------------------------
|
|
||||||
|
|
||||||
%% ZDW 1
|
|
||||||
lambda0_nm = [1310];
|
|
||||||
S0 = [0.075,0.095]';
|
|
||||||
% wavelength axis around ZDW
|
|
||||||
lambda_nm = linspace(1240, 1360, 400);
|
|
||||||
|
|
||||||
% exact dispersion model
|
|
||||||
D_exact_1 = (S0./4) .* ( ...
|
|
||||||
lambda_nm - (lambda0_nm^4)./(lambda_nm.^3) );
|
|
||||||
|
|
||||||
%% ZDW 2
|
|
||||||
lambda0_nm = [1320];
|
|
||||||
% exact dispersion model
|
|
||||||
D_exact_2 = (S0./4) .* ( ...
|
|
||||||
lambda_nm - (lambda0_nm^4)./(lambda_nm.^3) );
|
|
||||||
|
|
||||||
|
|
||||||
%% plot
|
|
||||||
figure('Color','w'); hold on;
|
|
||||||
cols = [0.6510 0.8078 0.8902;...
|
|
||||||
0.1216 0.4706 0.7059;...
|
|
||||||
0.6980 0.8745 0.5412;...
|
|
||||||
0.2000 0.6275 0.1725];
|
|
||||||
|
|
||||||
plot(lambda_nm, D_exact_1(1,:), 'LineWidth',2, 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
|
||||||
plot(lambda_nm, D_exact_1(2,:), 'LineWidth',2, 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
|
||||||
|
|
||||||
% plot(lambda_nm, D_exact_2(1,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
|
||||||
% plot(lambda_nm, D_exact_2(2,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
|
||||||
|
|
||||||
xlabel('Wavelength $\lambda$ [nm]','Interpreter','latex');
|
|
||||||
ylabel('D($\lambda$) [ps/(nm km)]','Interpreter','latex');
|
|
||||||
title('Chromatic Dispersion Around the ZDW');
|
|
||||||
legend('Location','best');
|
|
||||||
grid on; box on;
|
|
||||||
xlim([min(lambda_nm) max(lambda_nm)])
|
|
||||||
ylim([-5 5]);
|
|
||||||
|
|
||||||
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\dispersion')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
%% plot_dispersion_dual_ZDW
|
|
||||||
% Visualizes two ZDW fiber types, each with an S0 tolerance range.
|
|
||||||
|
|
||||||
%% plot_dispersion_minimal_for_tikz
|
|
||||||
% Minimal setup for clean TikZ tuning
|
|
||||||
|
|
||||||
% 1. Parameters
|
|
||||||
lambda_nm = linspace(1240, 1360, 400);
|
|
||||||
S0_range = [0.075, 0.095];
|
|
||||||
ZDW_range = [1300, 1325];
|
|
||||||
|
|
||||||
% 2. Calculate Envelope and Nominal
|
|
||||||
[S_mesh, Z_mesh] = meshgrid(S0_range, ZDW_range);
|
|
||||||
D_all = zeros(length(lambda_nm), 4);
|
|
||||||
for i = 1:4
|
|
||||||
D_all(:,i) = (S_mesh(i)/4) .* (lambda_nm - (Z_mesh(i)^4)./(lambda_nm.^3));
|
|
||||||
end
|
|
||||||
D_env_min = min(D_all, [], 2);
|
|
||||||
D_env_max = max(D_all, [], 2);
|
|
||||||
D_nominal = (mean(S0_range)/4) .* (lambda_nm - (mean(ZDW_range)^4)./(lambda_nm.^3));
|
|
||||||
|
|
||||||
% 3. Plotting
|
|
||||||
figure('Color','w'); hold on;
|
|
||||||
env_col = [0.1216, 0.4706, 0.7059];
|
|
||||||
|
|
||||||
% Shaded area
|
|
||||||
[hl, hp] = boundedline(lambda_nm, (D_env_min+D_env_max)/2, ...
|
|
||||||
(D_env_max-D_env_min)/2, 'alpha', 'cmap', env_col);
|
|
||||||
set(hl, 'YData', D_nominal, 'Color', 'k', 'LineWidth', 1.5);
|
|
||||||
|
|
||||||
% Generate the outline and capture the handle
|
|
||||||
ho = outlinebounds(hl, hp);
|
|
||||||
|
|
||||||
% Change properties
|
|
||||||
set(ho, 'Color', 'k', ... % Make it black
|
|
||||||
'LineStyle', '--', ... % Make it dashed
|
|
||||||
'LineWidth', 0.5, ... % Make it thin
|
|
||||||
'HandleVisibility', 'off'); % Hide from legend
|
|
||||||
|
|
||||||
% 4. "Minimal" Measurement Lines (Tweak these in TikZ later)
|
|
||||||
% Vertical measurement at 1290nm
|
|
||||||
lambda_v = 1290;
|
|
||||||
[~, idx] = min(abs(lambda_nm - lambda_v));
|
|
||||||
y_bot = D_env_min(idx);
|
|
||||||
y_top = D_env_max(idx);
|
|
||||||
|
|
||||||
% Simple line - in TikZ this will be a single \draw command
|
|
||||||
line([lambda_v, lambda_v], [y_bot, y_top], 'Color', 'r', 'LineWidth', 1.2, 'Tag', 'VertArrow');
|
|
||||||
text(lambda_v + 2, (y_top+y_bot)/2, '$\Delta D$', 'Color', 'r', 'Interpreter', 'latex');
|
|
||||||
|
|
||||||
% Horizontal measurement at D=0
|
|
||||||
z1 = ZDW_range(1);
|
|
||||||
z2 = ZDW_range(2);
|
|
||||||
line([z1, z2], [0, 0], 'Color', [0.1 0.5 0.1], 'LineWidth', 1.2, 'Tag', 'HorizArrow');
|
|
||||||
text(mean(ZDW_range), 0.5, '$\Delta \lambda_0$', 'Color', [0.1 0.5 0.1], ...
|
|
||||||
'Interpreter', 'latex', 'HorizontalAlignment', 'center');
|
|
||||||
|
|
||||||
% 5. Aesthetics
|
|
||||||
xlabel('Wavelength $\lambda$ [nm]', 'Interpreter', 'latex');
|
|
||||||
ylabel('$D(\lambda)$ [ps/(nm km)]', 'Interpreter', 'latex');
|
|
||||||
grid on; box on;
|
|
||||||
xlim([1240 1360]); ylim([-5 5]);
|
|
||||||
line(xlim, [0 0], 'Color', [0.4 0.4 0.4], 'LineStyle', '--', 'HandleVisibility', 'off');
|
|
||||||
|
|
||||||
% Legend using the handles we have
|
|
||||||
legend([hp, hl], {'Worst-case Envelope', 'Nominal Realization'}, ...
|
|
||||||
'Location', 'northwest', 'Interpreter', 'latex');
|
|
||||||
|
|
||||||
% To export, run:
|
|
||||||
% matlab2tikz('dispersion.tex', 'standalone', true);
|
|
||||||
|
|
||||||
%% plot_dispersion_for_tikz
|
|
||||||
% Optimized for matlab2tikz compatibility with manual arrows
|
|
||||||
|
|
||||||
%% plot_dispersion_statistical_envelopes
|
|
||||||
% Visualizes hard spec limits vs. 98% statistical distribution
|
|
||||||
|
|
||||||
%% plot_dispersion_final_for_tikz
|
%% plot_dispersion_final_for_tikz
|
||||||
lambda_nm = linspace(1240, 1360, 400);
|
lambda_nm = linspace(1240, 1360, 400);
|
||||||
|
|
||||||
@@ -181,6 +49,14 @@ for k = 1:size(scenarios, 1)
|
|||||||
% 'HandleVisibility', 'off'); % Hide from legend
|
% 'HandleVisibility', 'off'); % Hide from legend
|
||||||
% Capture Wide Spec (k=1) bounds for the TikZ measurement lines
|
% Capture Wide Spec (k=1) bounds for the TikZ measurement lines
|
||||||
hp.FaceAlpha = 0.5;
|
hp.FaceAlpha = 0.5;
|
||||||
|
% ho = outlinebounds(hl, hp);
|
||||||
|
% % Change properties
|
||||||
|
% set(ho, 'Color', 'k', ... % Make it black
|
||||||
|
% 'LineStyle', '--', ... % Make it dashed
|
||||||
|
% 'LineWidth', 1, ... % Make it thin
|
||||||
|
% 'HandleVisibility', 'off'); % Hide from legend
|
||||||
|
% Capture Wide Spec (k=1) bounds for the TikZ measurement lines
|
||||||
|
hp.FaceAlpha = 0.5;
|
||||||
else
|
else
|
||||||
hp.FaceAlpha = 0.8;
|
hp.FaceAlpha = 0.8;
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ hold on;
|
|||||||
lambda_levels = unique([50:-10:30, 30:-5:5]);
|
lambda_levels = unique([50:-10:30, 30:-5:5]);
|
||||||
|
|
||||||
% Contour plot
|
% Contour plot
|
||||||
[C,h] = contour(f_GHz, L_km, lambda_surface_nm, lambda_levels, ...
|
[C,h] = contourf(f_GHz, L_km, lambda_surface_nm, lambda_levels, ...
|
||||||
'LineWidth', 1.2, ...
|
'LineWidth', 1.2, ...
|
||||||
'ShowText', 'off');
|
'ShowText', 'off');
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ end
|
|||||||
|
|
||||||
%% Export
|
%% Export
|
||||||
% Hier erzwingen wir die rote Colormap für pgfplots, damit mat2tikz es nicht blau exportiert!
|
% Hier erzwingen wir die rote Colormap für pgfplots, damit mat2tikz es nicht blau exportiert!
|
||||||
mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/02_IMDD_System/tikz/dispersion/dispersion_power_fading_contour2.tikz");
|
% mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/02_IMDD_System/tikz/dispersion/dispersion_power_fading_contour2.tikz");
|
||||||
|
|
||||||
function [lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_target, L, lambda0, S0)
|
function [lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_target, L, lambda0, S0)
|
||||||
% lambda_for_first_null_full (stable, single-branch + validity checks)
|
% lambda_for_first_null_full (stable, single-branch + validity checks)
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ D_lambda = (S0/4) * (lambda*1e9 - (lambda0*1e9)^4/(lambda*1e9)^3); % ps/(nm·km)
|
|||||||
D_si = D_lambda * 1e-6; % → s/m²
|
D_si = D_lambda * 1e-6; % → s/m²
|
||||||
b2 = -D_si * lambda^2 / (2*pi*c); % s²/m
|
b2 = -D_si * lambda^2 / (2*pi*c); % s²/m
|
||||||
|
|
||||||
|
Dacc = D_lambda * L;
|
||||||
|
fprintf('Accumulated Dispersion: %.2f ps/nm \n', Dacc / 1e3);
|
||||||
|
|
||||||
%% Frequency grid
|
%% Frequency grid
|
||||||
f_max = 200e9;
|
f_max = 200e9;
|
||||||
f = linspace(0, f_max, 5000); % [Hz]
|
f = linspace(0, f_max, 5000); % [Hz]
|
||||||
|
|||||||
182
TEST_TODO.md
Normal file
182
TEST_TODO.md
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
# Test TODO
|
||||||
|
|
||||||
|
This file is the current backlog for building out the MATLAB test suite.
|
||||||
|
It should reflect the repository state now, not the original plan.
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
|
||||||
|
Fast profile status:
|
||||||
|
|
||||||
|
- `run_all_tests('profile','fast')`
|
||||||
|
- latest verified result: `Passed: 59 | Failed: 0 | Incomplete: 0`
|
||||||
|
- explicit placeholder tests remaining: `70`
|
||||||
|
|
||||||
|
Mandatory workflow for every future test-writing session:
|
||||||
|
|
||||||
|
1. Read the target class implementation in `Classes/...` before writing or changing tests.
|
||||||
|
2. Read the current placeholder or existing test in `Tests/...`.
|
||||||
|
3. Replace or extend the existing test. Do not create duplicate test files.
|
||||||
|
4. Use the existing `matlab.unittest` framework and extend `IMDDTestCase`.
|
||||||
|
5. Tag new tests with `TestTags`.
|
||||||
|
6. Run the relevant test entrypoint after implementation.
|
||||||
|
7. Do not consider the task complete until the test run result is checked.
|
||||||
|
|
||||||
|
## Completed Base Tests
|
||||||
|
|
||||||
|
These are already implemented and verified in the fast profile:
|
||||||
|
|
||||||
|
- `Classes/00_signals/Signal.m` -> `Tests/00_signals/Signal_test.m`
|
||||||
|
- `Classes/00_signals/Informationsignal.m` -> `Tests/00_signals/Informationsignal_test.m`
|
||||||
|
- `Classes/00_signals/Electricalsignal.m` -> `Tests/00_signals/Electricalsignal_test.m`
|
||||||
|
- `Classes/01_transmit/PAMmapper.m` -> `Tests/01_transmit/PAMmapper_test.m`
|
||||||
|
- `Classes/01_transmit/PAMsource.m` -> `Tests/01_transmit/PAMsource_test.m`
|
||||||
|
- `Classes/01_transmit/Pulseformer.m` -> `Tests/01_transmit/Pulseformer_test.m`
|
||||||
|
- `Classes/02_optical/Fiber.m` -> `Tests/02_optical/Fiber_test.m`
|
||||||
|
- `Classes/03_receive/Photodiode.m` -> `Tests/03_receive/Photodiode_test.m`
|
||||||
|
- `Classes/03_receive/Scope.m` -> `Tests/03_receive/Scope_test.m`
|
||||||
|
- `Classes/04_DSP/TransmissionPerformance.m` -> `Tests/04_DSP/TransmissionPerformance_test.m`
|
||||||
|
- `Classes/04_DSP/Equalizer/FFE.m` -> `Tests/04_DSP/Equalizer/FFE_test.m`
|
||||||
|
- `Classes/04_DSP/Sequence Detection/MLSE.m` -> `Tests/04_DSP/Sequence Detection/MLSE_test.m`
|
||||||
|
- `Classes/04_DSP/Timing Recovery/Timing_Recovery.m` -> `Tests/04_DSP/Timing Recovery/T_04_DSP_Timing_Recovery_Timing_Recovery_test.m`
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
- `Opticalsignal_test.m` still appears to be a placeholder and should be treated as unfinished.
|
||||||
|
- There are multiple `Timing_Recovery` class names in the repo, so the implemented base-class test currently uses the disambiguated file name:
|
||||||
|
`Tests/04_DSP/Timing Recovery/T_04_DSP_Timing_Recovery_Timing_Recovery_test.m`
|
||||||
|
|
||||||
|
## Next Priority Tests
|
||||||
|
|
||||||
|
Highest-value unfinished tests to implement next:
|
||||||
|
|
||||||
|
1. `Classes/00_signals/Opticalsignal.m`
|
||||||
|
`Tests/00_signals/Opticalsignal_test.m`
|
||||||
|
Focus:
|
||||||
|
- constructor metadata wiring
|
||||||
|
- `delay`
|
||||||
|
- `cspr`
|
||||||
|
- interaction with inherited signal behavior
|
||||||
|
|
||||||
|
2. `Classes/01_transmit/Signalgenerator.m`
|
||||||
|
`Tests/01_transmit/Signalgenerator_test.m`
|
||||||
|
Focus:
|
||||||
|
- constructor/config defaults
|
||||||
|
- deterministic generation path
|
||||||
|
- output type and shape
|
||||||
|
|
||||||
|
3. `Classes/02_etc/Filter.m`
|
||||||
|
`Tests/02_etc/Filter_test.m`
|
||||||
|
Focus:
|
||||||
|
- deterministic filter construction
|
||||||
|
- `process` behavior on small signals
|
||||||
|
- output rate/length invariants
|
||||||
|
|
||||||
|
4. `Classes/02_etc/Amplifier.m`
|
||||||
|
`Tests/02_etc/Amplifier_test.m`
|
||||||
|
Focus:
|
||||||
|
- gain behavior
|
||||||
|
- noise-free baseline
|
||||||
|
- output class and metadata behavior
|
||||||
|
|
||||||
|
5. `Classes/02_optical/EML.m`
|
||||||
|
`Tests/02_optical/EML_test.m`
|
||||||
|
Focus:
|
||||||
|
- deterministic modulation path
|
||||||
|
- output class and metadata
|
||||||
|
- small synthetic fixture only
|
||||||
|
|
||||||
|
6. `Classes/02_optical/Optical_Multiplex.m`
|
||||||
|
`Tests/02_optical/Optical_Multiplex_test.m`
|
||||||
|
Focus:
|
||||||
|
- combining channels
|
||||||
|
- output dimensions
|
||||||
|
- metadata handling
|
||||||
|
|
||||||
|
7. `Classes/02_optical/Optical_Demultiplex.m`
|
||||||
|
`Tests/02_optical/Optical_Demultiplex_test.m`
|
||||||
|
Focus:
|
||||||
|
- deterministic channel extraction
|
||||||
|
- output dimensions
|
||||||
|
- basic round-trip expectations with multiplexing if practical
|
||||||
|
|
||||||
|
8. `Classes/02_optical/Polarization_Controller.m`
|
||||||
|
`Tests/02_optical/Polarization_Controller_test.m`
|
||||||
|
Focus:
|
||||||
|
- deterministic transform behavior
|
||||||
|
- shape preservation
|
||||||
|
|
||||||
|
9. `Classes/02_optical/DP_Fiber.m`
|
||||||
|
`Tests/02_optical/DP_Fiber_test.m`
|
||||||
|
Focus:
|
||||||
|
- very small deterministic sanity checks only
|
||||||
|
- avoid long or GPU-heavy runs
|
||||||
|
|
||||||
|
## Next DSP Layer
|
||||||
|
|
||||||
|
After the items above, continue with these:
|
||||||
|
|
||||||
|
- `Classes/04_DSP/Coding/Duobinary.m`
|
||||||
|
`Tests/04_DSP/Coding/Duobinary_test.m`
|
||||||
|
- `Classes/04_DSP/Coding/MRDS_coding.m`
|
||||||
|
`Tests/04_DSP/Coding/MRDS_coding_test.m`
|
||||||
|
- `Classes/04_DSP/Sequence Detection/MLSE_viterbi.m`
|
||||||
|
`Tests/04_DSP/Sequence Detection/MLSE_viterbi_test.m`
|
||||||
|
- `Classes/04_DSP/Sequence Detection/MLSE_new.m`
|
||||||
|
`Tests/04_DSP/Sequence Detection/MLSE_new_test.m`
|
||||||
|
- `Classes/04_DSP/Timing Recovery/Time_Shifter.m`
|
||||||
|
`Tests/04_DSP/Timing Recovery/Time_Shifter_test.m`
|
||||||
|
- `Classes/04_DSP/Timing Recovery/Godard_Timing_Recovery.m`
|
||||||
|
`Tests/04_DSP/Timing Recovery/Godard_Timing_Recovery_test.m`
|
||||||
|
- `Classes/04_DSP/Timing Recovery/MaxVar_Timing_Recovery.m`
|
||||||
|
`Tests/04_DSP/Timing Recovery/MaxVar_Timing_Recovery_test.m`
|
||||||
|
|
||||||
|
Then move on to the remaining equalizer variants:
|
||||||
|
|
||||||
|
- `EQ.m`
|
||||||
|
- `EQ_copy.m`
|
||||||
|
- `EQ_silas*.m`
|
||||||
|
- `FFE_*`
|
||||||
|
- `ML_MLSE*.m`
|
||||||
|
- `Postfilter.m`
|
||||||
|
- `VNLE.m`
|
||||||
|
|
||||||
|
## Lower Priority Areas
|
||||||
|
|
||||||
|
Leave these for later unless a current task depends on them:
|
||||||
|
|
||||||
|
- `Classes/Warehouse_class/*`
|
||||||
|
- `Classes/DataBaseHandler/*`
|
||||||
|
- template/example classes like `class_template`
|
||||||
|
|
||||||
|
## Excluded From Automated Testing
|
||||||
|
|
||||||
|
Do not create or run automated tests for lab device classes in this repository.
|
||||||
|
|
||||||
|
Excluded area:
|
||||||
|
|
||||||
|
- `Classes/05_Lab/*`
|
||||||
|
|
||||||
|
Reason:
|
||||||
|
|
||||||
|
- the device IPs are reachable in this environment
|
||||||
|
- executing these classes can change instrument set points
|
||||||
|
- this can interfere with external or ongoing experiments
|
||||||
|
|
||||||
|
Rule for future sessions:
|
||||||
|
|
||||||
|
- do not implement `Tests/05_Lab/*`
|
||||||
|
- do not run files that communicate with lab devices
|
||||||
|
- do not add these classes back into the active TODO backlog unless explicitly requested by the user for a controlled setup
|
||||||
|
|
||||||
|
## Session Prompt Checklist
|
||||||
|
|
||||||
|
Every future agent prompt should include these requirements:
|
||||||
|
|
||||||
|
- read the class implementation first
|
||||||
|
- read the current test file second
|
||||||
|
- implement the test in the existing file
|
||||||
|
- prefer deterministic synthetic fixtures
|
||||||
|
- avoid plotting and hardware unless required
|
||||||
|
- never run or implement `05_Lab` tests in normal agent sessions
|
||||||
|
- run `run_all_tests('profile','fast')` after implementation
|
||||||
|
- report the changed files and the verification result
|
||||||
@@ -1,11 +1,79 @@
|
|||||||
classdef Electricalsignal_test < matlab.unittest.TestCase
|
classdef Electricalsignal_test < IMDDTestCase
|
||||||
% Test class for Electricalsignal
|
methods (Test, TestTags = {'unit', 'fast', 'signals', 'electricalsignal'})
|
||||||
|
function constructorStoresSignalFsAndLogbook(testCase)
|
||||||
|
seed = Signal(1, "fs", 2);
|
||||||
|
seed = seed.logbookentry("electrical seed", seed);
|
||||||
|
|
||||||
methods (Test)
|
elec = Electricalsignal([1; -2; 3], "fs", 80e9, "logbook", seed.logbook);
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for Electricalsignal
|
testCase.verifyClass(elec, 'Electricalsignal');
|
||||||
% Add your test code here
|
testCase.verifyEqual(elec.signal, [1; -2; 3]);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(elec.fs, 80e9);
|
||||||
|
testCase.verifyEqual(elec.logbook, seed.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function inheritedArithmeticKeepsElectricalsignalTypeAndMetadata(testCase)
|
||||||
|
seed = Signal(0, "fs", 1);
|
||||||
|
seed = seed.logbookentry("lhs metadata", seed);
|
||||||
|
lhs = Electricalsignal([1; 2; 3], "fs", 64e9, "logbook", seed.logbook);
|
||||||
|
rhs = Electricalsignal([4; 5; 6], "fs", 32e9, "logbook", table());
|
||||||
|
|
||||||
|
sumSig = lhs + rhs;
|
||||||
|
|
||||||
|
testCase.verifyClass(sumSig, 'Electricalsignal');
|
||||||
|
testCase.verifyEqual(sumSig.signal, [5; 7; 9]);
|
||||||
|
testCase.verifyEqual(sumSig.fs, lhs.fs);
|
||||||
|
testCase.verifyEqual(sumSig.logbook, lhs.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function informationCastPreservesSignalFsAndLogbook(testCase)
|
||||||
|
seed = Signal(3, "fs", 4);
|
||||||
|
seed = seed.logbookentry("electrical cast", seed);
|
||||||
|
elec = Electricalsignal([2; 0; -2], "fs", 96e9, "logbook", seed.logbook);
|
||||||
|
|
||||||
|
info = elec.Informationsignal("fs", elec.fs, "logbook", elec.logbook);
|
||||||
|
|
||||||
|
testCase.verifyClass(info, 'Informationsignal');
|
||||||
|
testCase.verifyEqual(info.signal, elec.signal);
|
||||||
|
testCase.verifyEqual(info.fs, elec.fs);
|
||||||
|
testCase.verifyEqual(info.logbook, elec.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function power50MatchesInheritedElectricalPowerDefinition(testCase)
|
||||||
|
elec = Electricalsignal([1; -1; 1; -1], "fs", 1, "logbook", table());
|
||||||
|
|
||||||
|
expectedPowerDbm = 10 * log10(mean(abs(elec.signal).^2) / 50) + 30;
|
||||||
|
|
||||||
|
testCase.verifyEqual(elec.power50(), expectedPowerDbm, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(elec.power50(), elec.power(), "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function csprUsesCarrierToTotalPowerRatioInDb(testCase)
|
||||||
|
elec = Electricalsignal([1; 3], "fs", 1, "logbook", table());
|
||||||
|
|
||||||
|
carrierPowerDbm = pow2db(abs(mean(elec.signal)).^2) + 30;
|
||||||
|
expectedCsprDb = carrierPowerDbm - elec.power();
|
||||||
|
|
||||||
|
testCase.verifyEqual(elec.cspr(), expectedCsprDb, "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function normalizeMilliwattSetsPowerToZeroDbmInto50Ohm(testCase)
|
||||||
|
elec = Electricalsignal([2; -2; 2; -2], "fs", 1, "logbook", table());
|
||||||
|
|
||||||
|
elec = elec.normalize("mode", normalization_mode.milliwatt);
|
||||||
|
|
||||||
|
testCase.verifyEqual(elec.power50(), 0, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyClass(elec, 'Electricalsignal');
|
||||||
|
end
|
||||||
|
|
||||||
|
function setPowerSupportsMilliwattAndDbwTargets(testCase)
|
||||||
|
elec = Electricalsignal([1; -1; 1; -1], "fs", 1, "logbook", table());
|
||||||
|
|
||||||
|
elecMilliwatt = elec.setPower(2, power_notation.mW);
|
||||||
|
elecDbw = elec.setPower(-20, power_notation.dBW);
|
||||||
|
|
||||||
|
testCase.verifyEqual(elecMilliwatt.power50(), 10 * log10(2), "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(elecDbw.power50(), 10, "AbsTol", 1e-12);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,82 @@
|
|||||||
classdef Informationsignal_test < matlab.unittest.TestCase
|
classdef Informationsignal_test < IMDDTestCase
|
||||||
% Test class for Informationsignal
|
methods (Test, TestTags = {'unit', 'fast', 'signals', 'informationsignal'})
|
||||||
|
function constructorWithoutOptionsUsesSignalDefaults(testCase)
|
||||||
|
info = Informationsignal([0; 1; 1; 0]);
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyClass(info, 'Informationsignal');
|
||||||
function testExample(testCase)
|
testCase.verifyEqual(info.signal, [0; 1; 1; 0]);
|
||||||
% Example test case for Informationsignal
|
testCase.verifyEmpty(info.fs);
|
||||||
% Add your test code here
|
testCase.verifyEmpty(info.logbook);
|
||||||
testCase.verifyTrue(true);
|
end
|
||||||
|
|
||||||
|
function constructorWithOptionsCopiesFsAndLogbook(testCase)
|
||||||
|
seed = Signal(5, "fs", 2);
|
||||||
|
seed = seed.logbookentry("seed entry", seed);
|
||||||
|
|
||||||
|
info = Informationsignal([1; 0; 1], "fs", 32e9, "logbook", seed.logbook);
|
||||||
|
|
||||||
|
testCase.verifyEqual(info.signal, [1; 0; 1]);
|
||||||
|
testCase.verifyEqual(info.fs, 32e9);
|
||||||
|
testCase.verifyEqual(info.logbook, seed.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function inheritedArithmeticKeepsInformationsignalTypeAndMetadata(testCase)
|
||||||
|
lhs = Informationsignal([1; 2; 3], "fs", 64e9, "logbook", table());
|
||||||
|
rhs = Informationsignal([4; 5; 6], "fs", 1, "logbook", table());
|
||||||
|
|
||||||
|
sumSig = lhs + rhs;
|
||||||
|
|
||||||
|
testCase.verifyClass(sumSig, 'Informationsignal');
|
||||||
|
testCase.verifyEqual(sumSig.signal, [5; 7; 9]);
|
||||||
|
testCase.verifyEqual(sumSig.fs, lhs.fs);
|
||||||
|
testCase.verifyEqual(sumSig.logbook, lhs.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function electricalsignalCastUsesRequestedFsAndLogbook(testCase)
|
||||||
|
seed = Signal(1, "fs", 4);
|
||||||
|
seed = seed.logbookentry("cast logbook", seed);
|
||||||
|
info = Informationsignal([0; 1; 0; 1]);
|
||||||
|
|
||||||
|
elec = info.Electricalsignal("fs", 128e9, "logbook", seed.logbook);
|
||||||
|
|
||||||
|
testCase.verifyClass(elec, 'Electricalsignal');
|
||||||
|
testCase.verifyEqual(elec.signal, info.signal);
|
||||||
|
testCase.verifyEqual(elec.fs, 128e9);
|
||||||
|
testCase.verifyEqual(elec.logbook, seed.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function opticalsignalCastFailsForInformationsignal(testCase)
|
||||||
|
info = Informationsignal([0; 1; 0; 1]);
|
||||||
|
|
||||||
|
didError = false;
|
||||||
|
try
|
||||||
|
info.Opticalsignal( ...
|
||||||
|
"fs", 64e9, ...
|
||||||
|
"logbook", info.logbook, ...
|
||||||
|
"lambda", 1310e-9, ...
|
||||||
|
"nase", 0, ...
|
||||||
|
"polrot", 0);
|
||||||
|
catch ME
|
||||||
|
didError = true;
|
||||||
|
testCase.verifySubstring(ME.message, ...
|
||||||
|
"Cannot convert from information- to opticalsignal.");
|
||||||
|
end
|
||||||
|
|
||||||
|
testCase.verifyTrue(didError, ...
|
||||||
|
"Informationsignal -> Opticalsignal should reject direct conversion.");
|
||||||
|
end
|
||||||
|
|
||||||
|
function electricalToInformationCastPreservesSignalAndMetadata(testCase)
|
||||||
|
seed = Signal(2, "fs", 8);
|
||||||
|
seed = seed.logbookentry("from electrical", seed);
|
||||||
|
elec = Electricalsignal([3; 1; 4], "fs", 96e9, "logbook", seed.logbook);
|
||||||
|
|
||||||
|
info = elec.Informationsignal("fs", elec.fs, "logbook", elec.logbook);
|
||||||
|
|
||||||
|
testCase.verifyClass(info, 'Informationsignal');
|
||||||
|
testCase.verifyEqual(info.signal, elec.signal);
|
||||||
|
testCase.verifyEqual(info.fs, elec.fs);
|
||||||
|
testCase.verifyEqual(info.logbook, elec.logbook);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Opticalsignal_test < matlab.unittest.TestCase
|
classdef Opticalsignal_test < IMDDTestCase
|
||||||
% Test class for Opticalsignal
|
% Auto-generated placeholder for Opticalsignal.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/00_signals/Opticalsignal.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Opticalsignal
|
testCase.assumeFail("Tests for Opticalsignal are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,117 @@
|
|||||||
classdef Signal_test < matlab.unittest.TestCase
|
classdef Signal_test < IMDDTestCase
|
||||||
% Test class for Signal
|
methods (Test, TestTags = {'unit', 'fast', 'signals'})
|
||||||
|
function constructorStoresSignalAndSamplingRate(testCase)
|
||||||
|
sig = Signal([1; 2; 3], "fs", 64e9);
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyEqual(sig.signal, [1; 2; 3]);
|
||||||
function testExample(testCase)
|
testCase.verifyEqual(sig.fs, 64e9);
|
||||||
% Example test case for Signal
|
testCase.verifyEmpty(sig.logbook);
|
||||||
% Add your test code here
|
end
|
||||||
testCase.verifyTrue(true);
|
|
||||||
|
function arithmeticOperatorsSupportSignalOperands(testCase)
|
||||||
|
x = Signal([1; 2; 3]);
|
||||||
|
y = Signal([4; 5; 6]);
|
||||||
|
|
||||||
|
sumSig = x + y;
|
||||||
|
diffSig = y - x;
|
||||||
|
prodSig = x .* y;
|
||||||
|
|
||||||
|
testCase.verifyEqual(sumSig.signal, [5; 7; 9]);
|
||||||
|
testCase.verifyEqual(diffSig.signal, [3; 3; 3]);
|
||||||
|
testCase.verifyEqual(prodSig.signal, [4; 10; 18]);
|
||||||
|
end
|
||||||
|
|
||||||
|
function arithmeticOperatorsSupportNumericOperands(testCase)
|
||||||
|
x = Signal([1; 2; 3]);
|
||||||
|
|
||||||
|
sumSig = x + 2;
|
||||||
|
diffSig = x - 1;
|
||||||
|
prodSig = x .* 3;
|
||||||
|
|
||||||
|
testCase.verifyEqual(sumSig.signal, [3; 4; 5]);
|
||||||
|
testCase.verifyEqual(diffSig.signal, [0; 1; 2]);
|
||||||
|
testCase.verifyEqual(prodSig.signal, [3; 6; 9]);
|
||||||
|
end
|
||||||
|
|
||||||
|
function lengthReturnsSignalLength(testCase)
|
||||||
|
sig = Signal(zeros(11, 1));
|
||||||
|
|
||||||
|
testCase.verifyEqual(sig.length(), 11);
|
||||||
|
end
|
||||||
|
|
||||||
|
function normalizeRmsScalesSignalToUnitPower(testCase)
|
||||||
|
sig = Signal([1; -1; 1; -1]);
|
||||||
|
|
||||||
|
sig = sig.normalize("mode", normalization_mode.rms);
|
||||||
|
|
||||||
|
testCase.verifyEqual(mean(abs(sig.signal).^2), 1, "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function normalizeOneOneMapsSignalToMinusOneToOne(testCase)
|
||||||
|
sig = Signal([2; 4; 6]);
|
||||||
|
|
||||||
|
sig = sig.normalize("mode", normalization_mode.oneone);
|
||||||
|
|
||||||
|
testCase.verifyEqual(sig.signal, [-1; 0; 1], "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function logbookEntryAppendsRowAndDescription(testCase)
|
||||||
|
sig = Signal([1; 0; -1], "fs", 1);
|
||||||
|
|
||||||
|
sig = sig.logbookentry("unit-test entry", sig);
|
||||||
|
|
||||||
|
testCase.verifyEqual(height(sig.logbook), 1);
|
||||||
|
testCase.verifyEqual(string(sig.logbook.SignalType(1)), "Signal");
|
||||||
|
testCase.verifyEqual(string(sig.logbook.Description(1)), "unit-test entry");
|
||||||
|
testCase.verifyEqual(string(sig.logbook.ModifierName(1)), "Signal");
|
||||||
|
end
|
||||||
|
|
||||||
|
function resampleWithIdenticalRatesKeepsSignalAndFs(testCase)
|
||||||
|
original = [1; 2; 3; 4];
|
||||||
|
sig = Signal(original, "fs", 8);
|
||||||
|
|
||||||
|
sig = sig.resample("fs_in", 8, "fs_out", 8);
|
||||||
|
|
||||||
|
testCase.verifyEqual(sig.signal, original);
|
||||||
|
testCase.verifyEqual(sig.fs, 8);
|
||||||
|
testCase.verifyEqual(height(sig.logbook), 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function resampleToNewRateUpdatesSamplingRate(testCase)
|
||||||
|
sig = Signal((1:8).', "fs", 8);
|
||||||
|
|
||||||
|
sig = sig.resample("fs_in", 8, "fs_out", 16);
|
||||||
|
|
||||||
|
testCase.verifyEqual(sig.fs, 16);
|
||||||
|
testCase.verifyNotEmpty(sig.signal);
|
||||||
|
testCase.verifyEqual(height(sig.logbook), 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function castingRoundTripPreservesSignalThroughAllDomains(testCase)
|
||||||
|
infoIn = Informationsignal([0; 1; 1; 0]);
|
||||||
|
|
||||||
|
elecFromInfo = infoIn.Electricalsignal("fs", 64e9, "logbook", infoIn.logbook);
|
||||||
|
optFromElec = elecFromInfo.Opticalsignal( ...
|
||||||
|
"fs", elecFromInfo.fs, ...
|
||||||
|
"logbook", elecFromInfo.logbook, ...
|
||||||
|
"lambda", 1310e-9, ...
|
||||||
|
"nase", 0, ...
|
||||||
|
"polrot", 0);
|
||||||
|
elecFromOpt = optFromElec.Electricalsignal("fs", optFromElec.fs, "logbook", optFromElec.logbook);
|
||||||
|
infoOut = elecFromOpt.Informationsignal("fs", elecFromOpt.fs, "logbook", elecFromOpt.logbook);
|
||||||
|
|
||||||
|
testCase.verifyClass(elecFromInfo, 'Electricalsignal');
|
||||||
|
testCase.verifyClass(optFromElec, 'Opticalsignal');
|
||||||
|
testCase.verifyClass(elecFromOpt, 'Electricalsignal');
|
||||||
|
testCase.verifyClass(infoOut, 'Informationsignal');
|
||||||
|
|
||||||
|
testCase.verifyEqual(infoOut.signal, infoIn.signal);
|
||||||
|
testCase.verifyEqual(elecFromInfo.fs, 64e9);
|
||||||
|
testCase.verifyEqual(optFromElec.fs, 64e9);
|
||||||
|
testCase.verifyEqual(elecFromOpt.fs, 64e9);
|
||||||
|
testCase.verifyEqual(infoOut.fs, 64e9);
|
||||||
|
testCase.verifyEqual(optFromElec.lambda, 1310e-9);
|
||||||
|
testCase.verifyEqual(optFromElec.nase, 0);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef AWG_test < matlab.unittest.TestCase
|
classdef AWG_test < IMDDTestCase
|
||||||
% Test class for AWG
|
% Auto-generated placeholder for AWG.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/AWG.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for AWG
|
testCase.assumeFail("Tests for AWG are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef ChannelFreqResp_test < matlab.unittest.TestCase
|
classdef ChannelFreqResp_test < IMDDTestCase
|
||||||
% Test class for ChannelFreqResp
|
% Auto-generated placeholder for ChannelFreqResp.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/ChannelFreqResp.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for ChannelFreqResp
|
testCase.assumeFail("Tests for ChannelFreqResp are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef M8196A_test < matlab.unittest.TestCase
|
classdef M8196A_test < IMDDTestCase
|
||||||
% Test class for M8196A
|
% Auto-generated placeholder for M8196A.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/M8196A.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for M8196A
|
testCase.assumeFail("Tests for M8196A are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef M8199A_test < matlab.unittest.TestCase
|
classdef M8199A_test < IMDDTestCase
|
||||||
% Test class for M8199A
|
% Auto-generated placeholder for M8199A.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/M8199A.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for M8199A
|
testCase.assumeFail("Tests for M8199A are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef M8199B_test < matlab.unittest.TestCase
|
classdef M8199B_test < IMDDTestCase
|
||||||
% Test class for M8199B
|
% Auto-generated placeholder for M8199B.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/M8199B.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for M8199B
|
testCase.assumeFail("Tests for M8199B are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,74 +1,69 @@
|
|||||||
classdef PAMmapper_test < matlab.unittest.TestCase
|
classdef PAMmapper_test < IMDDTestCase
|
||||||
|
methods (Test, TestTags = {'unit', 'fast', 'transmit', 'pammapper'})
|
||||||
|
|
||||||
properties
|
|
||||||
Tx_bits
|
|
||||||
PAMmapper
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (MethodSetupParameter)
|
function roundTripBitMappingForSupportedPamOrders(testCase)
|
||||||
% Define method-level parameters for PRBS and bit pattern
|
modulationOrders = [2, 4, 8];
|
||||||
useprbs = struct('false', 0, 'true', 1); % variations: {0, 1}
|
|
||||||
M = struct('M2', 2, 'M4', 4, 'M6', 6, 'M8', 8); % variations: {2, 4, 6, 8}
|
|
||||||
O = struct('O10', 10, 'O15', 15, 'O17', 17); % variations: {10, 15, 17}
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (TestParameter)
|
for M = modulationOrders
|
||||||
% Define test-level parameters for M and O
|
txBits = Informationsignal(allBitPatternsForOrder(M));
|
||||||
|
|
||||||
end
|
mapper = PAMmapper(M, 0);
|
||||||
|
mapped = mapper.map(txBits);
|
||||||
|
demapped = mapper.demap(mapped);
|
||||||
|
|
||||||
methods (TestMethodSetup)
|
testCase.verifyEqual(double(demapped.signal), double(txBits.signal), ...
|
||||||
|
sprintf("Roundtrip mapping failed for PAM-%d.", M));
|
||||||
function setupModulation(testCase, useprbs, M, O)
|
|
||||||
% Setup PRBS and bit pattern for the test case using parameters
|
|
||||||
|
|
||||||
% Setup PRBS parameters
|
|
||||||
N = 2^(O-1); % Length of PRBS
|
|
||||||
randkey = 1; % Random key for random stream
|
|
||||||
|
|
||||||
[~, seed] = prbs(O, 1); % Initialize first seed of PRBS
|
|
||||||
bitpattern = [];
|
|
||||||
if useprbs
|
|
||||||
for i = 1:log2(M)
|
|
||||||
[bitpattern(:, i), seed] = prbs(O, N, seed);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
s = RandStream('twister', 'Seed', randkey);
|
|
||||||
for i = 1:log2(M)
|
|
||||||
bitpattern(:, i) = randi(s, [0 1], N, 1);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if M == 6
|
function roundTripPam6ClassicMapping(testCase)
|
||||||
bitpattern = reshape(bitpattern, [], 1);
|
txBits = Informationsignal(pam6BitStream());
|
||||||
bitpattern = bitpattern(1:end-mod(length(bitpattern), 5));
|
|
||||||
|
mapper = PAMmapper(6, 0);
|
||||||
|
mapped = mapper.map(txBits);
|
||||||
|
demapped = mapper.demap(mapped);
|
||||||
|
|
||||||
|
testCase.verifyEqual(demapped.signal, txBits.signal, ...
|
||||||
|
"PAM-6 classic mapping should be lossless for aligned inputs.");
|
||||||
end
|
end
|
||||||
|
|
||||||
testCase.Tx_bits = Informationsignal(bitpattern);
|
function roundTripPam6EthMapping(testCase)
|
||||||
testCase.PAMmapper = PAMmapper(M, 0);
|
txBits = Informationsignal(pam6BitStream());
|
||||||
|
|
||||||
|
mapper = PAMmapper(6, 0, "eth_style", 1);
|
||||||
|
mapped = mapper.map(txBits);
|
||||||
|
demapped = mapper.demap(mapped);
|
||||||
|
|
||||||
|
expectedBits = txBits.signal(1:length(demapped.signal));
|
||||||
|
|
||||||
|
testCase.verifyEqual(demapped.signal, expectedBits, ...
|
||||||
|
"PAM-6 ETH mapping should be lossless for aligned inputs.");
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function quantizeMapsToNearestConstellationLevel(testCase)
|
||||||
|
mapper = PAMmapper(4, 0);
|
||||||
|
signalIn = Electricalsignal([-4.0; -0.2; 0.4; 2.9], "fs", 1);
|
||||||
|
|
||||||
|
quantized = mapper.quantize(signalIn);
|
||||||
|
expected = [-3; -1; 1; 3] ./ sqrt(5);
|
||||||
|
|
||||||
|
testCase.verifyEqual(quantized.signal, expected, "AbsTol", 1e-12);
|
||||||
end
|
end
|
||||||
|
|
||||||
methods (Test, ParameterCombination = 'sequential')
|
|
||||||
% Test with sequential combination of parameters
|
|
||||||
function testBackToBackMapping(testCase, M, useprbs, O)
|
|
||||||
% Test Bits -> Symbols -> Bits (Back-to-Back Mapping)
|
|
||||||
|
|
||||||
% Map bits to symbols
|
|
||||||
Symbols = testCase.PAMmapper.map(testCase.Tx_bits);
|
|
||||||
|
|
||||||
% Demap symbols back to bits
|
|
||||||
Rx_bits = testCase.PAMmapper.demap(Symbols);
|
|
||||||
|
|
||||||
% Validate BER is zero
|
|
||||||
[~, error_num, ber, ~] = calc_ber(testCase.Tx_bits.signal, Rx_bits.signal, ...
|
|
||||||
"skip_front", 0, "skip_end", 0, "returnErrorLocation", 1);
|
|
||||||
|
|
||||||
% Assert that BER is zero
|
|
||||||
testCase.verifyEqual(ber, 0, 'BER should be zero');
|
|
||||||
testCase.verifyEqual(error_num, 0, 'No errors should occur in the mapping process');
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function bits = allBitPatternsForOrder(M)
|
||||||
|
bitWidth = log2(M);
|
||||||
|
symbols = (0:M-1).';
|
||||||
|
bits = zeros(M, bitWidth);
|
||||||
|
|
||||||
|
for bitIdx = 1:bitWidth
|
||||||
|
bits(:, bitIdx) = bitget(symbols, bitWidth - bitIdx + 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function bits = pam6BitStream()
|
||||||
|
combinations = dec2bin(0:31, 5) - '0';
|
||||||
|
bits = reshape(combinations.', [], 1);
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,104 @@
|
|||||||
classdef PAMsource_test < matlab.unittest.TestCase
|
classdef PAMsource_test < IMDDTestCase
|
||||||
% Test class for PAMsource
|
methods (Test, TestTags = {'unit', 'fast', 'transmit', 'pamsource'})
|
||||||
|
function constructorStoresProvidedOptions(testCase)
|
||||||
|
src = PAMsource( ...
|
||||||
|
"order", 5, ...
|
||||||
|
"useprbs", false, ...
|
||||||
|
"M", 4, ...
|
||||||
|
"fsym", 8, ...
|
||||||
|
"randkey", 17, ...
|
||||||
|
"applypulseform", false, ...
|
||||||
|
"fs_out", 8, ...
|
||||||
|
"applyclipping", false);
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyEqual(src.order, 5);
|
||||||
function testExample(testCase)
|
testCase.verifyFalse(src.useprbs);
|
||||||
% Example test case for PAMsource
|
testCase.verifyEqual(src.M, 4);
|
||||||
% Add your test code here
|
testCase.verifyEqual(src.fsym, 8);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(src.randkey, 17);
|
||||||
|
testCase.verifyFalse(src.applypulseform);
|
||||||
|
testCase.verifyEqual(src.fs_out, 8);
|
||||||
|
testCase.verifyFalse(src.applyclipping);
|
||||||
|
testCase.verifyEmpty(src.pulseformer);
|
||||||
|
end
|
||||||
|
|
||||||
|
function deterministicProcessMatchesPamMapperAcrossOrders(testCase)
|
||||||
|
orders = [2, 4, 8];
|
||||||
|
sourceOrder = 5;
|
||||||
|
fs = 8;
|
||||||
|
seed = 17;
|
||||||
|
|
||||||
|
for M = orders
|
||||||
|
src = PAMsource( ...
|
||||||
|
"order", sourceOrder, ...
|
||||||
|
"useprbs", false, ...
|
||||||
|
"M", M, ...
|
||||||
|
"fsym", fs, ...
|
||||||
|
"randkey", seed, ...
|
||||||
|
"applypulseform", false, ...
|
||||||
|
"fs_out", fs, ...
|
||||||
|
"applyclipping", false);
|
||||||
|
|
||||||
|
[digiSig, symbols, bits] = src.process();
|
||||||
|
|
||||||
|
bitpattern = expectedBitpattern(M, sourceOrder, seed);
|
||||||
|
expectedBits = Informationsignal(bitpattern);
|
||||||
|
expectedSymbols = PAMmapper(M, 0).map(expectedBits);
|
||||||
|
|
||||||
|
testCase.verifyClass(digiSig, 'Informationsignal');
|
||||||
|
testCase.verifyClass(symbols, 'Informationsignal');
|
||||||
|
testCase.verifyClass(bits, 'Informationsignal');
|
||||||
|
testCase.verifyEqual(bits.signal, bitpattern);
|
||||||
|
testCase.verifyEqual(symbols.signal, expectedSymbols.signal);
|
||||||
|
testCase.verifyEqual(digiSig.signal, expectedSymbols.signal);
|
||||||
|
testCase.verifyEqual(digiSig.fs, fs);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function clippingLimitsAmplitudeToScaledConstellationRange(testCase)
|
||||||
|
M = 4;
|
||||||
|
sourceOrder = 5;
|
||||||
|
fs = 8;
|
||||||
|
seed = 3;
|
||||||
|
|
||||||
|
src = PAMsource( ...
|
||||||
|
"order", sourceOrder, ...
|
||||||
|
"useprbs", false, ...
|
||||||
|
"M", M, ...
|
||||||
|
"fsym", fs, ...
|
||||||
|
"randkey", seed, ...
|
||||||
|
"applypulseform", false, ...
|
||||||
|
"fs_out", fs, ...
|
||||||
|
"applyclipping", true, ...
|
||||||
|
"clipfactor", 0.5);
|
||||||
|
|
||||||
|
[digiSig, symbols, bits] = src.process();
|
||||||
|
|
||||||
|
expectedBits = expectedBitpattern(M, sourceOrder, seed);
|
||||||
|
expectedSymbols = PAMmapper(M, 0).map(Informationsignal(expectedBits));
|
||||||
|
lowerLimit = min(expectedSymbols.signal) * 0.5;
|
||||||
|
upperLimit = max(expectedSymbols.signal) * 0.5;
|
||||||
|
expectedClipped = expectedSymbols.signal;
|
||||||
|
expectedClipped(expectedClipped < lowerLimit) = lowerLimit;
|
||||||
|
expectedClipped(expectedClipped > upperLimit) = upperLimit;
|
||||||
|
|
||||||
|
testCase.verifyEqual(bits.signal, expectedBits);
|
||||||
|
testCase.verifyEqual(symbols.signal, expectedSymbols.signal);
|
||||||
|
testCase.verifyEqual(digiSig.signal, expectedClipped);
|
||||||
|
testCase.verifyEqual(digiSig.fs, fs);
|
||||||
|
testCase.verifyLessThanOrEqual(max(digiSig.signal), upperLimit);
|
||||||
|
testCase.verifyGreaterThanOrEqual(min(digiSig.signal), lowerLimit);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function bitpattern = expectedBitpattern(M, order, seed)
|
||||||
|
bitWidth = log2(M);
|
||||||
|
N = 2^(order - 1);
|
||||||
|
s = RandStream('twister', 'Seed', seed);
|
||||||
|
bitpattern = zeros(N, bitWidth);
|
||||||
|
|
||||||
|
for idx = 1:bitWidth
|
||||||
|
bitpattern(:, idx) = randi(s, [0 1], N, 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,120 @@
|
|||||||
classdef Pulseformer_test < matlab.unittest.TestCase
|
classdef Pulseformer_test < IMDDTestCase
|
||||||
% Test class for Pulseformer
|
methods (Test, TestTags = {'unit', 'fast', 'transmit', 'pulseformer'})
|
||||||
|
function constructorStoresConfiguredProperties(testCase)
|
||||||
|
pf = Pulseformer( ...
|
||||||
|
"fdac", 64e9, ...
|
||||||
|
"fsym", 16e9, ...
|
||||||
|
"pulse", pulseform.rrc, ...
|
||||||
|
"pulselength", 12, ...
|
||||||
|
"alpha", 0.2, ...
|
||||||
|
"matched", 1);
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyEqual(pf.fdac, 64e9);
|
||||||
function testExample(testCase)
|
testCase.verifyEqual(pf.fsym, 16e9);
|
||||||
% Example test case for Pulseformer
|
testCase.verifyEqual(pf.pulse, pulseform.rrc);
|
||||||
% Add your test code here
|
testCase.verifyEqual(pf.pulselength, 12);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(pf.alpha, 0.2);
|
||||||
|
testCase.verifyEqual(pf.matched, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processUsesSymbolRateFallbackAndUpdatesSignalMetadata(testCase)
|
||||||
|
fsym = 16e9;
|
||||||
|
fdac = 64e9;
|
||||||
|
tx = makeInformationsignal([1; 0; -1; 1; 1; 0], []);
|
||||||
|
pf = Pulseformer( ...
|
||||||
|
"fdac", fdac, ...
|
||||||
|
"fsym", fsym, ...
|
||||||
|
"pulse", pulseform.rc, ...
|
||||||
|
"pulselength", 8, ...
|
||||||
|
"alpha", 0.35, ...
|
||||||
|
"matched", 0);
|
||||||
|
|
||||||
|
rx = pf.process(tx);
|
||||||
|
expected = expectedPulseformerOutput(pf, tx);
|
||||||
|
|
||||||
|
testCase.verifyClass(rx, 'Informationsignal');
|
||||||
|
testCase.verifyEqual(rx.signal, expected, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(rx.fs, fdac);
|
||||||
|
testCase.verifyEqual(height(rx.logbook), height(tx.logbook) + 1);
|
||||||
|
testCase.verifyEqual(string(rx.logbook.Description(end)), "Applied Pulseshaping");
|
||||||
|
end
|
||||||
|
|
||||||
|
function matchedAndUnmatchedProcessingPreserveTheSameRealWaveform(testCase)
|
||||||
|
tx = makeInformationsignal([1; 0; 0; -1; 1; -1; 0; 1], 16e9);
|
||||||
|
|
||||||
|
unmatched = Pulseformer( ...
|
||||||
|
"fdac", 32e9, ...
|
||||||
|
"fsym", 16e9, ...
|
||||||
|
"pulse", pulseform.rrc, ...
|
||||||
|
"pulselength", 10, ...
|
||||||
|
"alpha", 0.15, ...
|
||||||
|
"matched", 0);
|
||||||
|
matched = Pulseformer( ...
|
||||||
|
"fdac", 32e9, ...
|
||||||
|
"fsym", 16e9, ...
|
||||||
|
"pulse", pulseform.rrc, ...
|
||||||
|
"pulselength", 10, ...
|
||||||
|
"alpha", 0.15, ...
|
||||||
|
"matched", 1);
|
||||||
|
|
||||||
|
rxUnmatched = unmatched.process(tx);
|
||||||
|
rxMatched = matched.process(tx);
|
||||||
|
|
||||||
|
testCase.verifyEqual(length(rxUnmatched.signal), length(rxMatched.signal));
|
||||||
|
testCase.verifyEqual(rxUnmatched.signal, rxMatched.signal, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(rxUnmatched.signal, expectedPulseformerOutput(unmatched, tx), "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(rxMatched.signal, expectedPulseformerOutput(matched, tx), "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processPreservesLengthForIntegerRateConversion(testCase)
|
||||||
|
tx = makeInformationsignal((1:5).', []);
|
||||||
|
pf = Pulseformer( ...
|
||||||
|
"fdac", 20e9, ...
|
||||||
|
"fsym", 5e9, ...
|
||||||
|
"pulse", pulseform.rc, ...
|
||||||
|
"pulselength", 6, ...
|
||||||
|
"alpha", 0.25, ...
|
||||||
|
"matched", 0);
|
||||||
|
|
||||||
|
rx = pf.process(tx);
|
||||||
|
|
||||||
|
testCase.verifyEqual(length(rx.signal), 20);
|
||||||
|
testCase.verifyEqual(rx.fs, 20e9);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sig = makeInformationsignal(values, fs)
|
||||||
|
base = Signal(values);
|
||||||
|
sig = Informationsignal(values, "fs", fs, "logbook", base.logbook);
|
||||||
|
end
|
||||||
|
|
||||||
|
function expected = expectedPulseformerOutput(pf, signalclass_in)
|
||||||
|
if isprop(signalclass_in, 'fs') && ~isempty(signalclass_in.fs)
|
||||||
|
f_in = signalclass_in.fs;
|
||||||
|
else
|
||||||
|
f_in = pf.fsym;
|
||||||
|
end
|
||||||
|
|
||||||
|
[p, q] = rat(pf.fdac / f_in);
|
||||||
|
fs_intermediate = f_in * p;
|
||||||
|
sps_filter = fs_intermediate / pf.fsym;
|
||||||
|
|
||||||
|
if pf.pulse == pulseform.rc
|
||||||
|
filtertype = 'normal';
|
||||||
|
else
|
||||||
|
filtertype = 'sqrt';
|
||||||
|
end
|
||||||
|
|
||||||
|
h = rcosdesign(pf.alpha, pf.pulselength, sps_filter, filtertype);
|
||||||
|
if pf.matched
|
||||||
|
h = conj(fliplr(h));
|
||||||
|
end
|
||||||
|
|
||||||
|
data_out_ = upfirdn(signalclass_in.signal, h, p, q);
|
||||||
|
delay_samples_intermediate = (length(h) - 1) / 2;
|
||||||
|
delay_samples_out = delay_samples_intermediate / q;
|
||||||
|
st = floor(delay_samples_out) + 1;
|
||||||
|
len_out = ceil(length(signalclass_in.signal) * p / q);
|
||||||
|
expected = data_out_(st : st + len_out - 1);
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Signalgenerator_test < matlab.unittest.TestCase
|
classdef Signalgenerator_test < IMDDTestCase
|
||||||
% Test class for Signalgenerator
|
% Auto-generated placeholder for Signalgenerator.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/01_transmit/Signalgenerator.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Signalgenerator
|
testCase.assumeFail("Tests for Signalgenerator are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Amplifier_test < matlab.unittest.TestCase
|
classdef Amplifier_test < IMDDTestCase
|
||||||
% Test class for Amplifier
|
% Auto-generated placeholder for Amplifier.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_etc/Amplifier.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Amplifier
|
testCase.assumeFail("Tests for Amplifier are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Filter_test < matlab.unittest.TestCase
|
classdef Filter_test < IMDDTestCase
|
||||||
% Test class for Filter
|
% Auto-generated placeholder for Filter.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_etc/Filter.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Filter
|
testCase.assumeFail("Tests for Filter are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef DP_Fiber_test < matlab.unittest.TestCase
|
classdef DP_Fiber_test < IMDDTestCase
|
||||||
% Test class for DP_Fiber
|
% Auto-generated placeholder for DP_Fiber.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_optical/DP_Fiber.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for DP_Fiber
|
testCase.assumeFail("Tests for DP_Fiber are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EML_test < matlab.unittest.TestCase
|
classdef EML_test < IMDDTestCase
|
||||||
% Test class for EML
|
% Auto-generated placeholder for EML.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_optical/EML.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EML
|
testCase.assumeFail("Tests for EML are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,87 @@
|
|||||||
classdef Fiber_test < matlab.unittest.TestCase
|
classdef Fiber_test < IMDDTestCase
|
||||||
% Test class for Fiber
|
methods (Test, TestTags = {'unit', 'fast', 'optical', 'fiber'})
|
||||||
|
function zeroLengthPropagationLeavesSignalUnchanged(testCase)
|
||||||
|
fiber = Fiber("fsimu", 64e9, "fiber_length", 0, "alpha", 0, "D", 0, ...
|
||||||
|
"Dslope", 0, "lambda0", 1310, "gamma", 0);
|
||||||
|
inputSig = makeOpticalsignal([1 + 1i; -2 + 0.5i; 0.25 - 0.75i], 64e9, 1310e-9);
|
||||||
|
|
||||||
methods (Test)
|
outputSig = fiber.process_(inputSig);
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for Fiber
|
testCase.verifyClass(outputSig, 'Opticalsignal');
|
||||||
% Add your test code here
|
testCase.verifyEqual(outputSig.signal, inputSig.signal, "AbsTol", 1e-12);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(outputSig.lambda, inputSig.lambda);
|
||||||
|
testCase.verifyEqual(outputSig.fs, inputSig.fs);
|
||||||
|
end
|
||||||
|
|
||||||
|
function attenuationOnlyMatchesAnalyticalFieldScaling(testCase)
|
||||||
|
fs = 32e9;
|
||||||
|
lambda = 1310e-9;
|
||||||
|
fiberLengthKm = 2.5;
|
||||||
|
alphaDbPerKm = 0.2;
|
||||||
|
inputSignal = [1 + 2i; -0.5 + 0.25i; 0.75 - 1.25i; 2 - 1i];
|
||||||
|
fiber = Fiber("fsimu", fs, "fiber_length", fiberLengthKm, "alpha", alphaDbPerKm, ...
|
||||||
|
"D", 0, "Dslope", 0, "lambda0", 1310, "gamma", 0);
|
||||||
|
inputSig = makeOpticalsignal(inputSignal, fs, lambda);
|
||||||
|
|
||||||
|
outputSig = fiber.process_(inputSig);
|
||||||
|
|
||||||
|
alphaLin = alphaDbPerKm / 10 * log(10) / 1e3;
|
||||||
|
expected = inputSignal .* exp(-alphaLin / 2 * fiber.fiber_length);
|
||||||
|
|
||||||
|
testCase.verifyEqual(outputSig.signal, expected, "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function linearOnlyPropagationPreservesShapeAndEnergyWhenLossless(testCase)
|
||||||
|
fs = 64e9;
|
||||||
|
lambda = 1310e-9;
|
||||||
|
inputSignal = [1 + 0.5i; -1i; 0.75; 2 - 0.25i];
|
||||||
|
fiber = Fiber("fsimu", fs, "fiber_length", 0.3, "alpha", 0, ...
|
||||||
|
"D", 0, "Dslope", 0, "lambda0", 1310, "gamma", 0);
|
||||||
|
inputSig = makeOpticalsignal(inputSignal, fs, lambda);
|
||||||
|
|
||||||
|
outputSig = fiber.process_(inputSig);
|
||||||
|
|
||||||
|
testCase.verifySize(outputSig.signal, size(inputSignal));
|
||||||
|
testCase.verifyEqual(outputSig.signal, inputSignal, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(norm(outputSig.signal), norm(inputSignal), "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processAddsLogbookEntryAndReturnsOpticalsignal(testCase)
|
||||||
|
fs = 32e9;
|
||||||
|
lambda = 1310e-9;
|
||||||
|
fiber = Fiber("fsimu", fs, "fiber_length", 0, "alpha", 0, "D", 0, ...
|
||||||
|
"Dslope", 0, "lambda0", 1310, "gamma", 0);
|
||||||
|
inputSig = makeOpticalsignal([1; -1; 2], fs, lambda);
|
||||||
|
|
||||||
|
outputSig = fiber.process(inputSig);
|
||||||
|
|
||||||
|
testCase.verifyClass(outputSig, 'Opticalsignal');
|
||||||
|
testCase.verifyEqual(outputSig.signal, inputSig.signal, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(height(outputSig.logbook), height(inputSig.logbook) + 1);
|
||||||
|
testCase.verifyEqual(string(outputSig.logbook.Description(end)), "Fiber ");
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sig = makeOpticalsignal(values, fs, lambda)
|
||||||
|
sig = Opticalsignal(values, ...
|
||||||
|
"fs", fs, ...
|
||||||
|
"logbook", emptyLogbook(), ...
|
||||||
|
"lambda", lambda, ...
|
||||||
|
"nase", 0, ...
|
||||||
|
"polrot", 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
function lb = emptyLogbook()
|
||||||
|
SignalType = [];
|
||||||
|
TimeStamp = [];
|
||||||
|
Length = [];
|
||||||
|
SignalPower = [];
|
||||||
|
Nase = [];
|
||||||
|
SignalCopy = [];
|
||||||
|
ModifierName = [];
|
||||||
|
ModifierCopy = {};
|
||||||
|
Description = [];
|
||||||
|
|
||||||
|
lb = table(SignalType, TimeStamp, Length, SignalPower, Nase, SignalCopy, ModifierName, ModifierCopy, Description);
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Optical_Demultiplex_test < matlab.unittest.TestCase
|
classdef Optical_Demultiplex_test < IMDDTestCase
|
||||||
% Test class for Optical_Demultiplex
|
% Auto-generated placeholder for Optical_Demultiplex.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_optical/Optical_Demultiplex.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Optical_Demultiplex
|
testCase.assumeFail("Tests for Optical_Demultiplex are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Optical_Multiplex_test < matlab.unittest.TestCase
|
classdef Optical_Multiplex_test < IMDDTestCase
|
||||||
% Test class for Optical_Multiplex
|
% Auto-generated placeholder for Optical_Multiplex.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_optical/Optical_Multiplex.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Optical_Multiplex
|
testCase.assumeFail("Tests for Optical_Multiplex are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Polarization_Controller_test < matlab.unittest.TestCase
|
classdef Polarization_Controller_test < IMDDTestCase
|
||||||
% Test class for Polarization_Controller
|
% Auto-generated placeholder for Polarization_Controller.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/02_optical/Polarization_Controller.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Polarization_Controller
|
testCase.assumeFail("Tests for Polarization_Controller are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef CNLSE_plain_test < matlab.unittest.TestCase
|
|
||||||
% Test class for CNLSE_plain
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for CNLSE_plain
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef CNLSE_test < matlab.unittest.TestCase
|
|
||||||
% Test class for CNLSE
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for CNLSE
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef canUseGPU_test < matlab.unittest.TestCase
|
|
||||||
% Test class for canUseGPU
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for canUseGPU
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef getNLstepsize_original_test < matlab.unittest.TestCase
|
|
||||||
% Test class for getNLstepsize_original
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for getNLstepsize_original
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef getNLstepsize_test < matlab.unittest.TestCase
|
|
||||||
% Test class for getNLstepsize
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for getNLstepsize
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef lin_step_original_test < matlab.unittest.TestCase
|
|
||||||
% Test class for lin_step_original
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for lin_step_original
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef lin_step_test < matlab.unittest.TestCase
|
|
||||||
% Test class for lin_step
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for lin_step
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef nl_step_original_test < matlab.unittest.TestCase
|
|
||||||
% Test class for nl_step_original
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for nl_step_original
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef nl_step_test < matlab.unittest.TestCase
|
|
||||||
% Test class for nl_step
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for nl_step
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef split_step_loop_test < matlab.unittest.TestCase
|
|
||||||
% Test class for split_step_loop
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for split_step_loop
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
10
Tests/03_electrical/CTLE_test.m
Normal file
10
Tests/03_electrical/CTLE_test.m
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
classdef CTLE_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for CTLE.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/03_electrical/CTLE.m
|
||||||
|
|
||||||
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
|
function testNotImplemented(testCase)
|
||||||
|
testCase.assumeFail("Tests for CTLE are not implemented yet.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
10
Tests/03_electrical/Electrical_Hybrid_test.m
Normal file
10
Tests/03_electrical/Electrical_Hybrid_test.m
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
classdef Electrical_Hybrid_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for Electrical_Hybrid.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/03_electrical/Electrical_Hybrid.m
|
||||||
|
|
||||||
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
|
function testNotImplemented(testCase)
|
||||||
|
testCase.assumeFail("Tests for Electrical_Hybrid are not implemented yet.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
10
Tests/03_electrical/Electrical_Trace_BiDi_test.m
Normal file
10
Tests/03_electrical/Electrical_Trace_BiDi_test.m
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
classdef Electrical_Trace_BiDi_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for Electrical_Trace_BiDi.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/03_electrical/Electrical_Trace_BiDi.m
|
||||||
|
|
||||||
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
|
function testNotImplemented(testCase)
|
||||||
|
testCase.assumeFail("Tests for Electrical_Trace_BiDi are not implemented yet.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
10
Tests/03_electrical/Electrical_Trace_test.m
Normal file
10
Tests/03_electrical/Electrical_Trace_test.m
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
classdef Electrical_Trace_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for Electrical_Trace.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/03_electrical/Electrical_Trace.m
|
||||||
|
|
||||||
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
|
function testNotImplemented(testCase)
|
||||||
|
testCase.assumeFail("Tests for Electrical_Trace are not implemented yet.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,11 +1,49 @@
|
|||||||
classdef Photodiode_test < matlab.unittest.TestCase
|
classdef Photodiode_test < IMDDTestCase
|
||||||
% Test class for Photodiode
|
methods (Test, TestTags = {'unit', 'fast', 'receive', 'photodiode'})
|
||||||
|
function processZeroNoiseBaselineMatchesAnalyticalExpectation(testCase)
|
||||||
|
pd = Photodiode("fsimu", 0, "responsivity", 2.5, "dark_current", 0.75, "nep", 0, "randomkey", 1);
|
||||||
|
xin = [1 + 1i, 2 - 1i; 0.5, 0.25i];
|
||||||
|
|
||||||
methods (Test)
|
yout = pd.process_(xin);
|
||||||
function testExample(testCase)
|
expected = 2.5 * sum(abs(xin).^2, 2) + 0.75;
|
||||||
% Example test case for Photodiode
|
|
||||||
% Add your test code here
|
testCase.verifyEqual(yout, expected, "AbsTol", 1e-12);
|
||||||
testCase.verifyTrue(true);
|
end
|
||||||
|
|
||||||
|
function responsivityScalesDetectedPowerLinearly(testCase)
|
||||||
|
xin = [1 + 2i, 0.5 - 0.5i; 0.25, 1i];
|
||||||
|
|
||||||
|
pd1 = Photodiode("fsimu", 0, "responsivity", 1, "dark_current", 0, "nep", 0, "randomkey", 1);
|
||||||
|
pd2 = Photodiode("fsimu", 0, "responsivity", 3.5, "dark_current", 0, "nep", 0, "randomkey", 1);
|
||||||
|
|
||||||
|
y1 = pd1.process_(xin);
|
||||||
|
y2 = pd2.process_(xin);
|
||||||
|
|
||||||
|
testCase.verifyEqual(y2, 3.5 * y1, "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function darkCurrentAddsConstantOffset(testCase)
|
||||||
|
xin = [1; 0; 2];
|
||||||
|
|
||||||
|
pdNoDc = Photodiode("fsimu", 0, "responsivity", 1.2, "dark_current", 0, "nep", 0, "randomkey", 1);
|
||||||
|
pdWithDc = Photodiode("fsimu", 0, "responsivity", 1.2, "dark_current", 0.42, "nep", 0, "randomkey", 1);
|
||||||
|
|
||||||
|
yNoDc = pdNoDc.process_(xin);
|
||||||
|
yWithDc = pdWithDc.process_(xin);
|
||||||
|
|
||||||
|
testCase.verifyEqual(yWithDc - yNoDc, 0.42 * ones(size(xin, 1), 1), "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function identicalSeedsProduceIdenticalStochasticOutputs(testCase)
|
||||||
|
xin = [1 + 1i; 0.5; 2];
|
||||||
|
|
||||||
|
pd1 = Photodiode("fsimu", 1, "responsivity", 0, "dark_current", 0, "nep", 1e-12, "randomkey", 7);
|
||||||
|
pd2 = Photodiode("fsimu", 1, "responsivity", 0, "dark_current", 0, "nep", 1e-12, "randomkey", 7);
|
||||||
|
|
||||||
|
y1 = pd1.process_(xin);
|
||||||
|
y2 = pd2.process_(xin);
|
||||||
|
|
||||||
|
testCase.verifyEqual(y1, y2);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,49 @@
|
|||||||
classdef Scope_test < matlab.unittest.TestCase
|
classdef Scope_test < IMDDTestCase
|
||||||
% Test class for Scope
|
methods (Test, TestTags = {'unit', 'fast', 'receive', 'scope'})
|
||||||
|
function quantizeMapsRealSignalToExpectedGrid(testCase)
|
||||||
|
scope = makeScope(10, 10, 2, 0, true);
|
||||||
|
xin = (0:9).';
|
||||||
|
|
||||||
methods (Test)
|
quantized = scope.quantize(xin);
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for Scope
|
expected = [0; 0; 8/3; 8/3; 16/3; 16/3; 16/3; 8; 8; 8];
|
||||||
% Add your test code here
|
testCase.verifyEqual(quantized, expected, "AbsTol", 1e-12);
|
||||||
testCase.verifyTrue(true);
|
end
|
||||||
|
|
||||||
|
function process_ResamplesQuantizesAndSubtractsDc(testCase)
|
||||||
|
scope = makeScope(40, 20, 3, 0, true);
|
||||||
|
xin = (1:40).';
|
||||||
|
|
||||||
|
yout = scope.process_(xin);
|
||||||
|
|
||||||
|
expected = scope.quantize(resample(xin, scope.fadc, scope.fsimu));
|
||||||
|
expected = expected - mean(expected, 1);
|
||||||
|
|
||||||
|
testCase.verifyEqual(length(yout), 20);
|
||||||
|
testCase.verifyEqual(yout, expected, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(mean(yout), 0, "AbsTol", 1e-12);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processWithoutDcBlockingPreservesQuantizedMean(testCase)
|
||||||
|
scope = makeScope(40, 20, 3, 0, false);
|
||||||
|
xin = (1:40).';
|
||||||
|
|
||||||
|
yout = scope.process_(xin);
|
||||||
|
|
||||||
|
expected = scope.quantize(resample(xin, scope.fadc, scope.fsimu));
|
||||||
|
|
||||||
|
testCase.verifyEqual(yout, expected, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyGreaterThan(abs(mean(yout)), 1e-12);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function scope = makeScope(fsimu, fadc, adcresolution, quantbuffer, block_dc)
|
||||||
|
scope = Scope( ...
|
||||||
|
"fsimu", fsimu, ...
|
||||||
|
"fadc", fadc, ...
|
||||||
|
"adcresolution", adcresolution, ...
|
||||||
|
"quantbuffer", quantbuffer, ...
|
||||||
|
"block_dc", block_dc, ...
|
||||||
|
"H_lpf", struct('fs', fadc));
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
classdef CIC_filter_test < matlab.unittest.TestCase
|
|
||||||
% Test class for CIC_filter
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
function testExample(testCase)
|
|
||||||
% Example test case for CIC_filter
|
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,137 +1,10 @@
|
|||||||
classdef Duobinary_test < matlab.unittest.TestCase
|
classdef Duobinary_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for Duobinary.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Coding/Duobinary.m
|
||||||
|
|
||||||
properties
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
%genereal properties of the test
|
function testNotImplemented(testCase)
|
||||||
ber
|
testCase.assumeFail("Tests for Duobinary are not implemented yet.");
|
||||||
errors
|
|
||||||
errorIndice
|
|
||||||
numbits
|
|
||||||
numsymbols
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (MethodSetupParameter)
|
|
||||||
% Define method-level parameters for PRBS and bit pattern
|
|
||||||
% i.e.: useprbs = {0,1};
|
|
||||||
useprbs = struct('true', 0); % variations: {0, 1}
|
|
||||||
M = struct('M2', 2, 'M4', 4, 'M6', 6, 'M8', 8); % variations: {2, 4, 6, 8}
|
|
||||||
O = struct('O10', 10,'O11', 11,'O12', 12,'O13', 13, 'O15', 15, 'O17', 17, 'O18', 18, 'O19', 19); % variations: {10, 15, 17}
|
|
||||||
end
|
|
||||||
|
|
||||||
properties (TestParameter)
|
|
||||||
% Define test-level parameters for M and O
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (TestMethodSetup, ParameterCombination = 'pairwise')
|
|
||||||
|
|
||||||
function setupTest(testCase, useprbs, M, O)
|
|
||||||
|
|
||||||
randkey = 1;
|
|
||||||
datarate = 448e9;
|
|
||||||
fsym = round(datarate / log2(M)) ;
|
|
||||||
|
|
||||||
%%%%% PRBS Generation in correct shape for Modulation Format %%%%%%
|
|
||||||
N = 2^(O-1); %length of prbs
|
|
||||||
[~,seed] = prbs(O,1); %initialize first seed of prbs
|
|
||||||
bitpattern=[];
|
|
||||||
|
|
||||||
if useprbs
|
|
||||||
%%%%% MOVE-IT PRMS %%%%
|
|
||||||
|
|
||||||
state = struct();
|
|
||||||
|
|
||||||
para = struct();
|
|
||||||
|
|
||||||
if M == 6
|
|
||||||
para.bl = 2^(O-2);
|
|
||||||
para.dimension = 5;
|
|
||||||
else
|
|
||||||
para.bl = 2^(O-1);
|
|
||||||
para.dimension = log2(M); %2.5bits/sym -> 2 bit/sym
|
|
||||||
end
|
|
||||||
|
|
||||||
para.rand = 0;
|
|
||||||
|
|
||||||
para.order = floor(O / log2(M));
|
|
||||||
para.skip =0;
|
|
||||||
para.bruijn = 0;
|
|
||||||
para.reset_prms = 0;
|
|
||||||
para.method = 1;
|
|
||||||
|
|
||||||
data_in = [];
|
|
||||||
global loop;
|
|
||||||
loop = 0;
|
|
||||||
[data_out,state_] = prms(data_in, state, para);
|
|
||||||
loop = 1;
|
|
||||||
[data_out,state_out] = prms(data_in, state_, para);
|
|
||||||
bitpattern = data_out';
|
|
||||||
|
|
||||||
%%%%% END MOVE-IT %%%%%%%
|
|
||||||
else
|
|
||||||
s = RandStream('twister','Seed',randkey);
|
|
||||||
for i = 1:log2(M)
|
|
||||||
bitpattern(:,i) = randi(s,[0 1], N, 1);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if M == 6
|
|
||||||
bitpattern = reshape(bitpattern',[],1);
|
|
||||||
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
|
||||||
end
|
|
||||||
|
|
||||||
testCase.numbits = length(bitpattern);
|
|
||||||
|
|
||||||
Tx_bits = Informationsignal(bitpattern);
|
|
||||||
|
|
||||||
Symbols_tx = PAMmapper(M,0).map(Tx_bits);
|
|
||||||
Symbols_tx.fs = fsym;
|
|
||||||
|
|
||||||
testCase.numsymbols = length(Symbols_tx);
|
|
||||||
|
|
||||||
Symbols_tx = PAMmapper(M,0).map(Tx_bits);
|
|
||||||
|
|
||||||
Symbols_tx.fs = fsym;
|
|
||||||
|
|
||||||
Symbols = Duobinary().precode(Symbols_tx);
|
|
||||||
|
|
||||||
Symbols = Duobinary().encode(Symbols);
|
|
||||||
|
|
||||||
Symbols = Duobinary().decode(Symbols);
|
|
||||||
|
|
||||||
Rx_bits = PAMmapper(M,0).demap(Symbols);
|
|
||||||
|
|
||||||
[bits,testCase.errors,testCase.ber,testCase.errorIndice] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
methods (Test)
|
|
||||||
% Test with sequential combination of parameters
|
|
||||||
|
|
||||||
function checkBerZero(testCase, useprbs, M, O)
|
|
||||||
% Assert that BER is zero
|
|
||||||
testCase.verifyEqual(testCase.ber, 0, ['Numer of Errors is not zero, found ',num2str(testCase.errors), ' errors at position ', num2str(testCase.errorIndice),' out of ', num2str(2^O)]);
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function checkBerCloseToZero(testCase, useprbs, M, O)
|
|
||||||
|
|
||||||
testCase.verifyLessThan(testCase.errors, 5, ['Found more than 5 errors. Found ',num2str(testCase.errors),' errors.']);
|
|
||||||
|
|
||||||
% if ~isempty(testCase.errorIndice)
|
|
||||||
% testCase.verifyEqual(testCase.errorIndice, 2^O , ['Error is NOT at the End but at: ', num2str(testCase.errorIndice),' of ', num2str(2^O)]);
|
|
||||||
% testCase.verifyEqual(testCase.errorIndice,1, ['Error is NOT at the Beginning but at: ', num2str(testCase.errorIndice),' of ', num2str(2^O)]);
|
|
||||||
% end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function checkSystemFailure(testCase, useprbs, M, O)
|
|
||||||
testCase.verifyLessThan(testCase.ber, 0.1, ['BER is higher than 10%. Soemthing is completely wrong! (BER is ',num2str(testCase.ber),')']);
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef MRDS_coding_test < matlab.unittest.TestCase
|
classdef MRDS_coding_test < IMDDTestCase
|
||||||
% Test class for MRDS_coding
|
% Auto-generated placeholder for MRDS_coding.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Coding/MRDS_coding.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for MRDS_coding
|
testCase.assumeFail("Tests for MRDS_coding are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_copy_test < matlab.unittest.TestCase
|
classdef EQ_copy_test < IMDDTestCase
|
||||||
% Test class for EQ_copy
|
% Auto-generated placeholder for EQ_copy.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ_copy.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ_copy
|
testCase.assumeFail("Tests for EQ_copy are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_silas_ofc_test < matlab.unittest.TestCase
|
classdef EQ_silas_ofc_test < IMDDTestCase
|
||||||
% Test class for EQ_silas_ofc
|
% Auto-generated placeholder for EQ_silas_ofc.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ_silas_ofc.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ_silas_ofc
|
testCase.assumeFail("Tests for EQ_silas_ofc are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_silas_plain_test < matlab.unittest.TestCase
|
classdef EQ_silas_plain_test < IMDDTestCase
|
||||||
% Test class for EQ_silas_plain
|
% Auto-generated placeholder for EQ_silas_plain.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ_silas_plain.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ_silas_plain
|
testCase.assumeFail("Tests for EQ_silas_plain are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_silas_sliding_window_dc_removal_test < matlab.unittest.TestCase
|
classdef EQ_silas_sliding_window_dc_removal_test < IMDDTestCase
|
||||||
% Test class for EQ_silas_sliding_window_dc_removal
|
% Auto-generated placeholder for EQ_silas_sliding_window_dc_removal.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ_silas_sliding_window_dc_removal.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ_silas_sliding_window_dc_removal
|
testCase.assumeFail("Tests for EQ_silas_sliding_window_dc_removal are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_silas_test < matlab.unittest.TestCase
|
classdef EQ_silas_test < IMDDTestCase
|
||||||
% Test class for EQ_silas
|
% Auto-generated placeholder for EQ_silas.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ_silas.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ_silas
|
testCase.assumeFail("Tests for EQ_silas are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef EQ_test < matlab.unittest.TestCase
|
classdef EQ_test < IMDDTestCase
|
||||||
% Test class for EQ
|
% Auto-generated placeholder for EQ.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/EQ.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for EQ
|
testCase.assumeFail("Tests for EQ are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_DCremoval_adaptive_mu_test < matlab.unittest.TestCase
|
classdef FFE_DCremoval_adaptive_mu_test < IMDDTestCase
|
||||||
% Test class for FFE_DCremoval_adaptive_mu
|
% Auto-generated placeholder for FFE_DCremoval_adaptive_mu.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_DCremoval_adaptive_mu.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_DCremoval_adaptive_mu
|
testCase.assumeFail("Tests for FFE_DCremoval_adaptive_mu are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_DCremoval_level_test < matlab.unittest.TestCase
|
classdef FFE_DCremoval_level_test < IMDDTestCase
|
||||||
% Test class for FFE_DCremoval_level
|
% Auto-generated placeholder for FFE_DCremoval_level.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_DCremoval_level.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_DCremoval_level
|
testCase.assumeFail("Tests for FFE_DCremoval_level are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_DCremoval_test < matlab.unittest.TestCase
|
classdef FFE_DCremoval_test < IMDDTestCase
|
||||||
% Test class for FFE_DCremoval
|
% Auto-generated placeholder for FFE_DCremoval.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_DCremoval.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_DCremoval
|
testCase.assumeFail("Tests for FFE_DCremoval are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_DFE_test < matlab.unittest.TestCase
|
classdef FFE_DFE_test < IMDDTestCase
|
||||||
% Test class for FFE_DFE
|
% Auto-generated placeholder for FFE_DFE.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_DFE.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_DFE
|
testCase.assumeFail("Tests for FFE_DFE are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_FFDCAVG_test < matlab.unittest.TestCase
|
classdef FFE_FFDCAVG_test < IMDDTestCase
|
||||||
% Test class for FFE_FFDCAVG
|
% Auto-generated placeholder for FFE_FFDCAVG.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_FFDCAVG.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_FFDCAVG
|
testCase.assumeFail("Tests for FFE_FFDCAVG are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_Kalman_Feedback_test < matlab.unittest.TestCase
|
classdef FFE_Kalman_Feedback_test < IMDDTestCase
|
||||||
% Test class for FFE_Kalman_Feedback
|
% Auto-generated placeholder for FFE_Kalman_Feedback.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_Kalman_Feedback.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_Kalman_Feedback
|
testCase.assumeFail("Tests for FFE_Kalman_Feedback are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_Kalman_test < matlab.unittest.TestCase
|
classdef FFE_Kalman_test < IMDDTestCase
|
||||||
% Test class for FFE_Kalman
|
% Auto-generated placeholder for FFE_Kalman.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_Kalman.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_Kalman
|
testCase.assumeFail("Tests for FFE_Kalman are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_MLSE_test < matlab.unittest.TestCase
|
classdef FFE_MLSE_test < IMDDTestCase
|
||||||
% Test class for FFE_MLSE
|
% Auto-generated placeholder for FFE_MLSE.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_MLSE.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_MLSE
|
testCase.assumeFail("Tests for FFE_MLSE are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef FFE_adaptive_decision_test < matlab.unittest.TestCase
|
classdef FFE_adaptive_decision_test < IMDDTestCase
|
||||||
% Test class for FFE_adaptive_decision
|
% Auto-generated placeholder for FFE_adaptive_decision.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/FFE_adaptive_decision.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for FFE_adaptive_decision
|
testCase.assumeFail("Tests for FFE_adaptive_decision are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,78 @@
|
|||||||
classdef FFE_test < matlab.unittest.TestCase
|
classdef FFE_test < IMDDTestCase
|
||||||
% Test class for FFE
|
methods (Test, TestTags = {'unit', 'fast', 'dsp', 'ffe'})
|
||||||
|
function constructorStoresDefaultsAndInitialState(testCase)
|
||||||
|
ffe = FFE();
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyEqual(ffe.sps, 2);
|
||||||
function testExample(testCase)
|
testCase.verifyEqual(ffe.order, 15);
|
||||||
% Example test case for FFE
|
testCase.verifyEqual(ffe.len_tr, 4096);
|
||||||
% Add your test code here
|
testCase.verifyEqual(ffe.mu_tr, 0);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(ffe.epochs_tr, 5);
|
||||||
|
testCase.verifyEqual(ffe.adaption_technique, adaption_method.lms);
|
||||||
|
testCase.verifyEqual(ffe.dd_mode, 1);
|
||||||
|
testCase.verifyEqual(ffe.mu_dd, 1e-5);
|
||||||
|
testCase.verifyEqual(ffe.epochs_dd, 5);
|
||||||
|
testCase.verifyFalse(ffe.decide);
|
||||||
|
testCase.verifyEqual(ffe.e, zeros(ffe.order, 1));
|
||||||
|
testCase.verifyEqual(ffe.error, 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
function noUpdateModeKeepsWeightsAtZeroAndPreservesSamplingRate(testCase)
|
||||||
|
x = makeSignal([-1; 1; -1; 1], 32e9);
|
||||||
|
d = makeSignal([-1; 1; -1; 1], 8e9);
|
||||||
|
|
||||||
|
ffe = FFE( ...
|
||||||
|
"sps", 1, ...
|
||||||
|
"order", 1, ...
|
||||||
|
"len_tr", length(x), ...
|
||||||
|
"mu_tr", 0, ...
|
||||||
|
"epochs_tr", 1, ...
|
||||||
|
"mu_dd", 0, ...
|
||||||
|
"epochs_dd", 1, ...
|
||||||
|
"dd_mode", 0, ...
|
||||||
|
"decide", false, ...
|
||||||
|
"adaption_technique", adaption_method.lms);
|
||||||
|
|
||||||
|
[y, noi] = ffe.process(x, d);
|
||||||
|
|
||||||
|
testCase.verifyEqual(ffe.e, 0);
|
||||||
|
testCase.verifyEqual(ffe.e_tr, 0);
|
||||||
|
testCase.verifyEqual(y.signal, zeros(size(x.signal)), "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(y.fs, d.fs);
|
||||||
|
testCase.verifyEqual(noi.signal, -d.signal, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(length(y.signal), length(x.signal));
|
||||||
|
end
|
||||||
|
|
||||||
|
function trainingModeLearnsFromTinySyntheticChannel(testCase)
|
||||||
|
x = makeSignal([1; -1; 1; -1], 16e9);
|
||||||
|
d = makeSignal([1; -1; 1; -1], 4e9);
|
||||||
|
|
||||||
|
ffe = FFE( ...
|
||||||
|
"sps", 1, ...
|
||||||
|
"order", 1, ...
|
||||||
|
"len_tr", length(x), ...
|
||||||
|
"mu_tr", 0.5, ...
|
||||||
|
"epochs_tr", 1, ...
|
||||||
|
"mu_dd", 0, ...
|
||||||
|
"epochs_dd", 1, ...
|
||||||
|
"dd_mode", 0, ...
|
||||||
|
"decide", false, ...
|
||||||
|
"adaption_technique", adaption_method.lms);
|
||||||
|
|
||||||
|
[y, noi] = ffe.process(x, d);
|
||||||
|
|
||||||
|
testCase.verifyEqual(y.fs, d.fs);
|
||||||
|
testCase.verifyClass(y, 'Informationsignal');
|
||||||
|
testCase.verifyClass(noi, 'Informationsignal');
|
||||||
|
testCase.verifyNotEqual(ffe.e, 0);
|
||||||
|
testCase.verifyNotEqual(ffe.e_tr, 0);
|
||||||
|
testCase.verifyNotEqual(y.signal, zeros(size(x.signal)));
|
||||||
|
testCase.verifyEqual(length(y.signal), length(x.signal));
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function sig = makeSignal(values, fs)
|
||||||
|
base = Signal(values);
|
||||||
|
sig = Informationsignal(values, "fs", fs, "logbook", base.logbook);
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef ML_MLSE_GPU_test < matlab.unittest.TestCase
|
classdef ML_MLSE_GPU_test < IMDDTestCase
|
||||||
% Test class for ML_MLSE_GPU
|
% Auto-generated placeholder for ML_MLSE_GPU.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/ML_MLSE_GPU.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for ML_MLSE_GPU
|
testCase.assumeFail("Tests for ML_MLSE_GPU are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef ML_MLSE_test < matlab.unittest.TestCase
|
classdef ML_MLSE_test < IMDDTestCase
|
||||||
% Test class for ML_MLSE
|
% Auto-generated placeholder for ML_MLSE.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/ML_MLSE.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for ML_MLSE
|
testCase.assumeFail("Tests for ML_MLSE are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Postfilter_test < matlab.unittest.TestCase
|
classdef Postfilter_test < IMDDTestCase
|
||||||
% Test class for Postfilter
|
% Auto-generated placeholder for Postfilter.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/Postfilter.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Postfilter
|
testCase.assumeFail("Tests for Postfilter are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef VNLE_test < matlab.unittest.TestCase
|
classdef VNLE_test < IMDDTestCase
|
||||||
% Test class for VNLE
|
% Auto-generated placeholder for VNLE.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Equalizer/VNLE.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for VNLE
|
testCase.assumeFail("Tests for VNLE are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef MLSE_new_test < matlab.unittest.TestCase
|
classdef MLSE_new_test < IMDDTestCase
|
||||||
% Test class for MLSE_new
|
% Auto-generated placeholder for MLSE_new.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Sequence Detection/MLSE_new.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for MLSE_new
|
testCase.assumeFail("Tests for MLSE_new are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,84 @@
|
|||||||
classdef MLSE_test < matlab.unittest.TestCase
|
classdef MLSE_test < IMDDTestCase
|
||||||
% Test class for MLSE
|
methods (Test, TestTags = {'unit', 'fast', 'dsp', 'mlse'})
|
||||||
|
function constructorStoresConfiguration(testCase)
|
||||||
|
mlse = MLSE( ...
|
||||||
|
"M", 4, ...
|
||||||
|
"DIR", [1 0.35], ...
|
||||||
|
"trellis_states", [-3 -1 1 3], ...
|
||||||
|
"duobinary_output", false, ...
|
||||||
|
"trellis_state_mode", 2, ...
|
||||||
|
"trellis_exclusion", 0, ...
|
||||||
|
"scale_mode", 0, ...
|
||||||
|
"debug", 0);
|
||||||
|
|
||||||
methods (Test)
|
testCase.verifyEqual(mlse.M, 4);
|
||||||
function testExample(testCase)
|
testCase.verifyEqual(mlse.DIR, [1 0.35]);
|
||||||
% Example test case for MLSE
|
testCase.verifyEqual(mlse.trellis_states, [-3 -1 1 3]);
|
||||||
% Add your test code here
|
testCase.verifyFalse(mlse.duobinary_output);
|
||||||
testCase.verifyTrue(true);
|
testCase.verifyEqual(mlse.trellis_state_mode, 2);
|
||||||
|
testCase.verifyEqual(mlse.trellis_exclusion, 0);
|
||||||
|
testCase.verifyEqual(mlse.scale_mode, 0);
|
||||||
|
testCase.verifyEqual(mlse.debug, 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processRecoversKnownPAM4Sequence(testCase)
|
||||||
|
[txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture();
|
||||||
|
|
||||||
|
txSignal = Informationsignal(txSymbols, "fs", 1);
|
||||||
|
rxSignal = Signal(rxSymbols, "fs", 1);
|
||||||
|
|
||||||
|
hdSignal = mlse.process(rxSignal, txSignal);
|
||||||
|
rxBits = PAMmapper(4, 0).demap(hdSignal);
|
||||||
|
|
||||||
|
testCase.verifyClass(hdSignal, "Signal");
|
||||||
|
testCase.verifyEqual(hdSignal.fs, rxSignal.fs);
|
||||||
|
testCase.verifyEqual(rxBits.signal, txBits, ...
|
||||||
|
"MLSE should recover the transmitted PAM-4 bits on the deterministic fixture.");
|
||||||
|
end
|
||||||
|
|
||||||
|
function processReturnsExpectedShapesAndFiniteMetric(testCase)
|
||||||
|
[txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture();
|
||||||
|
|
||||||
|
[viterbiSymbols, llr, gmi] = mlse.process_(rxSymbols, txSymbols);
|
||||||
|
rxBits = PAMmapper(4, 0).demap(viterbiSymbols(:));
|
||||||
|
expectedSymbols = txSymbols(:) ./ rms(txSymbols(:));
|
||||||
|
|
||||||
|
testCase.verifyEqual(numel(viterbiSymbols), numel(rxSymbols));
|
||||||
|
testCase.verifyEqual(size(llr), [numel(rxSymbols), 2]);
|
||||||
|
testCase.verifyTrue(isfinite(gmi));
|
||||||
|
testCase.verifyEqual(viterbiSymbols(:), expectedSymbols, "AbsTol", 1e-12);
|
||||||
|
testCase.verifyEqual(rxBits, txBits, ...
|
||||||
|
"Lower-level MLSE output should decode the same deterministic fixture.");
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function [txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture()
|
||||||
|
txBits = [ ...
|
||||||
|
0 0; ...
|
||||||
|
0 1; ...
|
||||||
|
1 1; ...
|
||||||
|
1 0; ...
|
||||||
|
0 1; ...
|
||||||
|
1 0; ...
|
||||||
|
0 0; ...
|
||||||
|
1 1];
|
||||||
|
|
||||||
|
mapper = PAMmapper(4, 0);
|
||||||
|
txSignal = Informationsignal(txBits);
|
||||||
|
txSymbols = mapper.map(txSignal).signal;
|
||||||
|
|
||||||
|
channel = [1 0.35];
|
||||||
|
rxSymbols = filter(channel, 1, txSymbols);
|
||||||
|
rxSymbols = rxSymbols + 0.01 * [0; 1; -1; 2; -2; 1; -1; 0];
|
||||||
|
|
||||||
|
mlse = MLSE( ...
|
||||||
|
"M", 4, ...
|
||||||
|
"DIR", channel, ...
|
||||||
|
"trellis_states", mapper.levels, ...
|
||||||
|
"duobinary_output", false, ...
|
||||||
|
"trellis_state_mode", 2, ...
|
||||||
|
"trellis_exclusion", 0, ...
|
||||||
|
"scale_mode", 0, ...
|
||||||
|
"debug", 0);
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef MLSE_viterbi_test < matlab.unittest.TestCase
|
classdef MLSE_viterbi_test < IMDDTestCase
|
||||||
% Test class for MLSE_viterbi
|
% Auto-generated placeholder for MLSE_viterbi.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Sequence Detection/MLSE_viterbi.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for MLSE_viterbi
|
testCase.assumeFail("Tests for MLSE_viterbi are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
10
Tests/04_DSP/T_04_DSP_Timing_Recovery_test.m
Normal file
10
Tests/04_DSP/T_04_DSP_Timing_Recovery_test.m
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
classdef T_04_DSP_Timing_Recovery_test < IMDDTestCase
|
||||||
|
% Auto-generated placeholder for Timing_Recovery.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing_Recovery.m
|
||||||
|
|
||||||
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
|
function testNotImplemented(testCase)
|
||||||
|
testCase.assumeFail("Tests for Timing_Recovery are not implemented yet.");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Godard_Timing_Recovery_test < matlab.unittest.TestCase
|
classdef Godard_Timing_Recovery_test < IMDDTestCase
|
||||||
% Test class for Godard_Timing_Recovery
|
% Auto-generated placeholder for Godard_Timing_Recovery.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing Recovery/Godard_Timing_Recovery.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Godard_Timing_Recovery
|
testCase.assumeFail("Tests for Godard_Timing_Recovery are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef MaxVar_Timing_Recovery_test < matlab.unittest.TestCase
|
classdef MaxVar_Timing_Recovery_test < IMDDTestCase
|
||||||
% Test class for MaxVar_Timing_Recovery
|
% Auto-generated placeholder for MaxVar_Timing_Recovery.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing Recovery/MaxVar_Timing_Recovery.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for MaxVar_Timing_Recovery
|
testCase.assumeFail("Tests for MaxVar_Timing_Recovery are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
classdef T_04_DSP_Timing_Recovery_Timing_Recovery_test < IMDDTestCase
|
||||||
|
methods (Test, TestTags = {'unit', 'fast', 'dsp', 'timing-recovery'})
|
||||||
|
function constructorAppliesDefaultConfiguration(testCase)
|
||||||
|
tr = Timing_Recovery();
|
||||||
|
|
||||||
|
testCase.verifyEqual(tr.modulation, 'PAM/PSK/QAM');
|
||||||
|
testCase.verifyEqual(tr.timing_error_detector, 'Gardner');
|
||||||
|
testCase.verifyEqual(tr.sps, 2);
|
||||||
|
testCase.verifyEqual(tr.damping_factor, 1.0);
|
||||||
|
testCase.verifyEqual(tr.normalized_loop_bandwidth, 0.005);
|
||||||
|
testCase.verifyEqual(tr.detector_gain, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
function constructorStoresConfiguredProperties(testCase)
|
||||||
|
tr = Timing_Recovery( ...
|
||||||
|
"modulation", 'PAM/PSK/QAM', ...
|
||||||
|
"timing_error_detector", 'Gardner', ...
|
||||||
|
"sps", 4, ...
|
||||||
|
"damping_factor", 0.75, ...
|
||||||
|
"normalized_loop_bandwidth", 0.02, ...
|
||||||
|
"detector_gain", 1.5);
|
||||||
|
|
||||||
|
testCase.verifyEqual(tr.modulation, 'PAM/PSK/QAM');
|
||||||
|
testCase.verifyEqual(tr.timing_error_detector, 'Gardner');
|
||||||
|
testCase.verifyEqual(tr.sps, 4);
|
||||||
|
testCase.verifyEqual(tr.damping_factor, 0.75);
|
||||||
|
testCase.verifyEqual(tr.normalized_loop_bandwidth, 0.02);
|
||||||
|
testCase.verifyEqual(tr.detector_gain, 1.5);
|
||||||
|
end
|
||||||
|
|
||||||
|
function processSignalsMissingCommunicationsToolboxClearly(testCase)
|
||||||
|
tr = Timing_Recovery("sps", 2);
|
||||||
|
inputSignal = Informationsignal([1; -1; 1; -1], "fs", 2);
|
||||||
|
|
||||||
|
testCase.verifyError(@() tr.process(inputSignal), 'MATLAB:undefinedVarOrClass');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Time_Shifter_test < matlab.unittest.TestCase
|
classdef Time_Shifter_test < IMDDTestCase
|
||||||
% Test class for Time_Shifter
|
% Auto-generated placeholder for Time_Shifter.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing Recovery/Time_Shifter.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Time_Shifter
|
testCase.assumeFail("Tests for Time_Shifter are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Timing_Recovery_GPT_test < matlab.unittest.TestCase
|
classdef Timing_Recovery_GPT_test < IMDDTestCase
|
||||||
% Test class for Timing_Recovery_GPT
|
% Auto-generated placeholder for Timing_Recovery_GPT.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing Recovery/Timing_Recovery_GPT.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Timing_Recovery_GPT
|
testCase.assumeFail("Tests for Timing_Recovery_GPT are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
classdef Timing_Recovery_Move_It_test < matlab.unittest.TestCase
|
classdef Timing_Recovery_Move_It_test < IMDDTestCase
|
||||||
% Test class for Timing_Recovery_Move_It
|
% Auto-generated placeholder for Timing_Recovery_Move_It.
|
||||||
|
% Target: C:/Users/Silas/Documents/MATLAB/imdd_simulation/Classes/04_DSP/Timing Recovery/Timing_Recovery_Move_It.m
|
||||||
|
|
||||||
methods (Test)
|
methods (Test, TestTags = {'placeholder', 'todo'})
|
||||||
function testExample(testCase)
|
function testNotImplemented(testCase)
|
||||||
% Example test case for Timing_Recovery_Move_It
|
testCase.assumeFail("Tests for Timing_Recovery_Move_It are not implemented yet.");
|
||||||
% Add your test code here
|
|
||||||
testCase.verifyTrue(true);
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user