Auswertung Experiment

Database tüddelei
DBHanlder läuft gut für DIESE Datanbank struktur...
App begonnen aber weit entfernt von gutem Stand
This commit is contained in:
sioe
2024-11-15 16:51:37 +01:00
parent 553ed19b9f
commit 397cfa61dd
219 changed files with 584 additions and 854 deletions

View File

@@ -254,7 +254,12 @@ classdef Signal
CallingModifier = evalin('caller','obj');
end
if isa(CallingModifier,"Signal")
CallingModifierStruct = obj.objToStructFilteredRecursive(CallingModifier);
ModifierCopy = {CallingModifierStruct};
end
ModifierCopy = {CallingModifier};
SignalType = [string(class(obj))];
TimeStamp = [(datetime('now','TimeZone','local','Format','HH:mm:ss'))];
@@ -263,7 +268,7 @@ classdef Signal
Nase = [0];
SignalCopy = obj.signal;
ModifierName = class(CallingModifier);
ModifierCopy = {CallingModifierStruct};
cell = {SignalType , TimeStamp , Length , SignalPower(1) , Nase, SignalCopy, ModifierName, ModifierCopy, Description};

View File

@@ -1,4 +1,4 @@
classdef EQ %< handle
classdef EQ < handle
%EQ Summary of this class goes here
% Detailed explanation goes here
@@ -289,9 +289,9 @@ classdef EQ %< handle
e_dc = e_dc - obj.DCmu*error;
obj.error_log.e_ffe(cnt,trainloops) = e_ffe;
obj.error_log.e_dfe(cnt,trainloops) = e_dfe;
obj.error_log.e_(cnt,trainloops) = error;
% obj.error_log.e_ffe(cnt,trainloops) = e_ffe;
% obj.error_log.e_dfe(cnt,trainloops) = e_dfe;
% obj.error_log.e_(cnt,trainloops) = error;
cnt = cnt+1;
if obj.Nb(1) > 0
@@ -460,7 +460,7 @@ classdef EQ %< handle
if 1%mu_mat ~= 0
e_dc = e_dc - obj.DCmu*error;
error_log(cnt,dd_loop) = e_dc;
% error_log(cnt,dd_loop) = e_dc;
cnt = cnt+1;
end

View File

@@ -0,0 +1,60 @@
classdef Postfilter < handle
%NAME Summary of this class goes here
% Detailed explanation goes here
properties(Access=public)
ncoeff = 2;
burg_coeff = [];
end
methods (Access=public)
function obj = Postfilter(options)
%NAME Construct an instance of this class
% Detailed explanation goes here
arguments
options.ncoeff double = 2
end
%
fn = fieldnames(options);
for n = 1:numel(fn)
try
obj.(fn{n}) = options.(fn{n});
end
end
% do more stuff
end
function signalclass_out = process(obj,signalclass_in,noiseclass_in)
obj.burg_coeff = arburg(noiseclass_in.signal,obj.ncoeff);
signalclass_in = signalclass_in.filter(obj.burg_coeff,1);
% append to logbook
lbdesc = ['Postfilter'];
signalclass_in = signalclass_in.logbookentry(lbdesc);
% write to output
signalclass_out = signalclass_in;
end
function showFilter(obj,noiseclass_in)
noiseclass_in.spectrum('displayname','Noise PSD shifted to 0dBm','fignum',123,'normalizeTo0dB',1);
[h,w] = freqz(1,obj.burg_coeff,length(noiseclass_in),"whole",noiseclass_in.fs);
h = h/max(abs(h));
hold on
w_ = (w - noiseclass_in.fs/2);
plot(w_.*1e-9,20*log10(fftshift(h)),'DisplayName',['Burg Coeffs: ', num2str(obj.burg_coeff), ' ']);
end
end
end

View File

@@ -1,4 +1,4 @@
classdef MLSE
classdef MLSE < handle
%MLSE calculates the most probable sequence for an input signal with given/ known channel impulse response of any length
properties(Access=public)

View File

@@ -38,6 +38,18 @@ classdef DBHandler < handle
error('Failed to connect to the database: %s', e.message);
end
if obj.dbIsHealthy
obj.refresh();
else
error('DB seems to be corrupt')
end
end
function obj = refresh(obj)
% Get table names and the first rows of each table to understand the structure
obj.getTableNames();
obj.getTables();
@@ -86,10 +98,10 @@ classdef DBHandler < handle
obj.distinctValues = struct();
% Iterate over each table in obj.tables
tableNames = fieldnames(obj.tables);
tableNames_ = fieldnames(obj.tables);
for i = 1:numel(tableNames)
tableName = tableNames{i};
for i = 1:numel(tableNames_)
tableName = tableNames_{i};
% Initialize a sub-struct to store distinct values for each field in the table
obj.distinctValues.(tableName) = struct();
@@ -101,10 +113,10 @@ classdef DBHandler < handle
for j = 1:numel(fieldNames)
fieldName = fieldNames{j};
% Skip fields ending with '_id' as they don't contain useful distinct values
if endsWith(fieldName, '_id')
continue;
end
% % Skip fields ending with '_id' as they don't contain useful distinct values
% if endsWith(fieldName, '_id')
% continue;
% end
% Construct SQL to get distinct values for the current field
query = sprintf('SELECT DISTINCT %s FROM %s', fieldName, tableName);
@@ -123,17 +135,38 @@ classdef DBHandler < handle
obj.distinctValues.(tableName).(fieldName) = distinctValues;
catch e
warning('Failed to retrieve distinct values for %s.%s: %s', tableName, fieldName, e.message);
% warning('Failed to retrieve distinct values for %s.%s: %s', tableName, fieldName, e.message);
obj.distinctValues.(tableName).(fieldName) = [];
end
end
end
% Display the distinct values (optional, for debugging purposes)
disp('Distinct values for each field:');
disp(obj.distinctValues);
end
function healthyDB = dbIsHealthy(obj)
healthyDB = false;
num_runs = obj.fetch('SELECT COUNT(*) AS total_runs FROM Runs');
num_configs = obj.fetch('SELECT COUNT(*) AS total_configurations FROM Configurations');
num_meas = obj.fetch('SELECT COUNT(*) AS total_measurements FROM Measurements');
assert((num_runs{1,1}==num_configs{1,1})&&(num_configs{1,1}==num_meas{1,1}),'Different num of entries per table');
%Check for any duplicate paths
duplictae_raw = obj.fetch("SELECT COALESCE(Runs.rx_raw_path,'NaN') AS rx_raw_path, COUNT(*) AS occurrences FROM Runs GROUP BY rx_raw_path HAVING COUNT(*) > 1");
duplictae_sync = obj.fetch("SELECT COALESCE(Runs.rx_sync_path,'NaN') AS rx_sync_path, COUNT(*) AS occurrences FROM Runs GROUP BY rx_sync_path HAVING COUNT(*) > 1");
if size(duplictae_raw,2) > 1
for i = 1:size(duplictae_raw,2)-1
fprintf('Raw Rx Paths: Found %d duplictaes of %s \n',duplictae_raw.occurrences(i),duplictae_raw.rx_raw_path(i));
end
end
healthyDB = true;
end
function lastID = appendToTable(obj, tableName, newRow)
% appendToTable Appends a new row to the specified table
@@ -241,11 +274,87 @@ classdef DBHandler < handle
end
end
function addBEREntry(obj, berValue, occurrence, runID, ffe, dfe, mlse, pf, eqType, ffe_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, comment)
% addBEREntry Adds a BER entry linked to an existing or new Equalizer entry.
% Usage:
% addBEREntry(runID, eq, ffe, dfe, mlse, pf, eqType, ffe_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, berValue, comment)
if isempty(pf)
postfilter_taps = [];
else
postfilter_taps = pf.burg_coeff;
end
% Create equalizer data struct for searching and adding if necessary
equalizerData = struct( ...
'ffe', jsonencode(ffe), ...
'dfe', jsonencode(dfe), ...
'mlse', jsonencode(mlse), ...
'pf', jsonencode(pf), ...
'eq_type', string(eqType), ...
'ffe_order', jsonencode(ffe_order), ...
'dfe_order', jsonencode(dfe_order), ...
'postfilter_taps',jsonencode(postfilter_taps),...
'len_tr', len_tr, ...
'mu_ffe', jsonencode(mu_ffe), ...
'mu_dfe', mu_dfe, ...
'mu_dc', mu_dc, ...
'comment', comment ...
);
% Check if exact Equalizer and BER entries already exist in the DB ...
selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','BERs.ber',['BERs.occurrence' ...
'']};
filterParams = obj.tables;
filterParams.Equalizer = equalizerData;
[dataTable,sql_query] = obj.queryDB(filterParams, selectedFields);
% get or insert Equalizer
if ~isempty(dataTable)
% Equalizer entry already exists, use the existing eq_id
cur_eq_id = dataTable.eq_id;
else
% Insert the new Equalizer entry
cur_eq_id = obj.appendToTable('Equalizer', equalizerData);
end
% skip if already here or insert BER entry
if ~isempty(dataTable)
% A BER entry with the same eq_id, run_id, and occurrence already exists
existingBERValue = dataTable.ber;
% Compare the existing BER value with the new BER value
if existingBERValue == berValue
fprintf('The BER entry %.2e || -- eq_id: %d -- run_id: %d -- occurrence: %d already exists. \n',berValue, cur_eq_id, runID, occurrence);
else
fprintf('Already found BER for EQ: %.2e ~= %.2e || -- eq_id: %d -- run_id: %d -- occurrence: %d already exists.\n', berValue, existingBERValue, cur_eq_id, runID, occurrence);
end
else
% No such BER entry exists, insert the new BER entry
berData = struct( ...
'run_id', runID, ...
'eq_id', cur_eq_id, ...
'ber', berValue, ...
'occurrence', occurrence ...
);
obj.appendToTable('BERs', berData);
end
end
function answer = fetch(obj,query)
answer = fetch(obj.conn,query);
end
function result = getPathsWithFlexibleFilter(obj, filterParams, selectedFields)
function [result,query] = queryDB(obj, filterParams, selectedFields)
% getPathsWithFlexibleFilter Retrieves values from Runs table with flexible filtering
% and lets the user select which fields to include in the SELECT statement.
%
@@ -257,8 +366,9 @@ classdef DBHandler < handle
% If left empty, two popup windows will prompt the user for input.
%
% Outputs:
% rxRawPaths: Cell array of values from the Runs table matching the criteria.
% filteredValues: Table of distinct values for parameters included in filterParams.
% result: table with sql return
% query: this was send to SQL DB
arguments
obj
filterParams = [];
@@ -299,7 +409,7 @@ classdef DBHandler < handle
fieldName = fieldParts{2};
if isnumeric(obj.tables.(tableName).(fieldName))
selectClause = [selectClause, 'COALESCE(', selectedFields{i}, ', -1) AS ', fieldName];
selectClause = [selectClause, 'COALESCE(', selectedFields{i}, ', ''NaN'') AS ', fieldName];
else
selectClause = [selectClause, 'COALESCE(', selectedFields{i}, ', '''') AS ', fieldName];
end
@@ -321,10 +431,10 @@ classdef DBHandler < handle
% Loop through each table in filterParams
filterClauses = [];
tableNames = fieldnames(filterParams);
tableNames_ = fieldnames(filterParams);
for t = 1:numel(tableNames)
tableName = tableNames{t};
for t = 1:numel(tableNames_)
tableName = tableNames_{t};
tableParams = filterParams.(tableName);
% Loop through each parameter in the table
@@ -343,12 +453,14 @@ classdef DBHandler < handle
elseif isnumeric(value) && isnan(value)
% If value is NaN, use IS NULL in SQL
filterClause = sprintf('%s IS NULL', fullName);
elseif isnumeric(value)
elseif isnumeric(value) && ~isEnumeration(value)
filterClause = sprintf('%s = %f', fullName, value);
elseif islogical(value) || (isnumeric(value) && ismember(value, [0, 1]))
elseif islogical(value) || (isnumeric(value) && ismember(value, [0, 1])) && ~isEnumeration(value)
filterClause = sprintf('%s = %d', fullName, value);
elseif ischar(value) || isstring(value)
filterClause = sprintf('%s = "%s"', fullName, value);
filterClause = sprintf('%s = ''%s''', fullName, char(value)); %nicht nach string suchen sondern nach chararray -> 'bla' statt "bla"
elseif isEnumeration(value)
filterClause = sprintf('%s = ''%s''', fullName, value);
else
error('Unsupported data type for field "%s".', fullName);
end
@@ -376,6 +488,7 @@ classdef DBHandler < handle
end
function selectedFields = promptSelectFields(obj)
% promptSelectFields Prompts the user to select fields from multiple tables to include in the SELECT statement using settingsdlg.
@@ -436,41 +549,67 @@ classdef DBHandler < handle
% promptFilterParameters Prompts the user to enter filter parameters using the settingsdlg framework.
% Get all possible parameters from all tables (excluding sqlite_sequence)
tableNames = fieldnames(obj.tables);
tableNames = setdiff(tableNames, {'sqlite_sequence'}); % Remove sqlite_sequence
tableNames_ = fieldnames(obj.tables);
tableNames_ = setdiff(tableNames_, {'sqlite_sequence'}); % Remove sqlite_sequence
% Prepare the inputs for settingsdlg with sections and separators
promptSettings = {};
allFieldsFullName = {};
convertedFieldNames = {};
for i = 1:numel(tableNames)
for i = 1:numel(tableNames_)
% Add a separator for each table section
promptSettings{end + 1} = 'separator';
promptSettings{end + 1} = tableNames{i};
promptSettings{end + 1} = tableNames_{i};
% Get all fields from the current table
tableFields = fieldnames(obj.tables.(tableNames{i}));
tableFields = fieldnames(obj.tables.(tableNames_{i}));
% Prepare each field to be added to the dialog
for j = 1:numel(tableFields)
fieldName = tableFields{j};
fullName = sprintf('%s.%s', tableNames{i}, fieldName);
fullName = sprintf('%s.%s', tableNames_{i}, fieldName);
convertedName = strrep(fullName, '.', '_'); % Replace '.' with '_'
% Skip fields that do not have distinct values stored
if ~isfield(obj.distinctValues.(tableNames_{i}), fieldName)
continue;
end
% Get the distinct values for the field
distinctValues_ = obj.distinctValues.(tableNames_{i}).(fieldName);
% Prepare distinct values for dropdown
if isempty(distinctValues_)
% If there are no distinct values, use only an "All" entry
distinctValues_ = {'All'};
else
% Ensure distinctValues is a cell array of strings
if isnumeric(distinctValues_)
distinctValues_ = arrayfun(@(x) num2str(x), distinctValues_, 'UniformOutput', false);
elseif isstring(distinctValues_)
distinctValues_ = cellstr(distinctValues_);
elseif iscell(distinctValues_) && ~iscellstr(distinctValues_)
distinctValues_ = cellfun(@num2str, distinctValues_, 'UniformOutput', false);
end
% Add an "All" option at the beginning of the distinct values list
distinctValues_ = [{'All'}; distinctValues_];
end
allFieldsFullName{end + 1} = fullName; % Add full name to the list
convertedFieldNames{end + 1} = convertedName; % Store the converted name
% Add the field name and value setting to the prompt
promptSettings{end + 1} = {sprintf('%s', fullName), convertedName};
promptSettings{end + 1} = [];
promptSettings{end + 1} = distinctValues_; % Add distinct values as dropdown options
end
end
% Create the settings dialog
[settings, button] = settingsdlg(...
'title', 'Input Parameters for Filtering', ...
'description', 'Enter the values for each field to filter. Leave empty to include all values. Type NaN for NULL.', ...
'description', 'Enter the values for each field to filter. Select "All" to include all values.', ...
promptSettings{:} ...
);
@@ -497,7 +636,7 @@ classdef DBHandler < handle
end
% Assign values to the respective fields under each table
if isempty(value)
if strcmp(value, 'All')
filterParams.(tableName).(fieldName) = []; % Set to empty to include all values
elseif isnumeric(value) && isnan(value)
filterParams.(tableName).(fieldName) = NaN; % Use NaN to handle as NULL
@@ -510,5 +649,6 @@ classdef DBHandler < handle
end
end

9
Datatypes/db_mode.m Normal file
View File

@@ -0,0 +1,9 @@
classdef db_mode < int32
enumeration
no_db (0)
db_precoded (1)
db_encoded (2)
end
end

View File

@@ -0,0 +1,11 @@
classdef equalizer_structure < int32
enumeration
ffe (0)
vnle (1)
vnle_pf_mlse (2)
db_precoded (3)
db_encoded (4)
end
end

11
Datatypes/isEnumeration.m Normal file
View File

@@ -0,0 +1,11 @@
function result = isEnumeration(value)
% isEnumeration Checks if a given value is an instance of an enumeration class
% Usage:
% result = isEnumeration(value);
% Get meta information about the class of the value
metaInfo = metaclass(value);
% Check if the meta information indicates an enumeration class
result = metaInfo.Enumeration;
end

View File

@@ -1,4 +1,15 @@
function duobinary_signaling()
function [eq_signal,eq_noise,ber,numErrors] = duobinary_signaling(EQ, MLSE,M ,rx_signal, tx_symbols, tx_bits)
%Duobinary Signaling
[eq_signal, eq_noise] = EQ.process(rx_signal,tx_symbols);
eq_signal = MLSE.process(eq_signal);
eq_signal = Duobinary().decode(eq_signal);
% M = numel(unique(eq_signal.signal));
rx_bits = PAMmapper(M,0).demap(eq_signal);
[~,numErrors,ber,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
end

View File

@@ -1,4 +1,17 @@
function duobinary_target()
function [eq_signal,eq_noise,ber,numErrors] = duobinary_target(EQ, MLSE,M, rx_signal, tx_symbols, tx_bits)
%Duobinary Targeting
[eq_signal, eq_noise] = EQ.process(rx_signal,Duobinary().encode(tx_symbols));
% dir = [1,1];
eq_signal = MLSE.process(eq_signal);
eq_signal = Duobinary().decode(eq_signal);
% M = numel(unique(tx_symbols.signal));
rx_bits = PAMmapper(M,0).demap(eq_signal);
[~,numErrors,ber,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
end

View File

@@ -1,4 +1,25 @@
function eq_signal = vnle(EQ,rx_signal,tx_symbols)
%VNLE
eq_signal = EQ.process(rx_signal,tx_symbols);
function [eq_signal,eq_noise,ber,numErrors] = vnle(EQ,M,rx_signal,tx_symbols,tx_bits)
%VNLE Apply an equalization algorithm to the received signal and calculate BER
% This function takes an equalizer object, a received signal, and the
% transmitted symbols to apply equalization, map the received signal back to bits,
% and compute the bit error rate (BER).
%
% Inputs:
% EQ - Equalizer object that provides the equalization method
% rx_signal - Received signal that needs to be equalized
% tx_symbols - Transmitted symbols used as a reference for BER calculation
%
% Outputs:
% eq_signal - Equalized version of the received signal
% ber - Bit error rate after equalization
% numErrors - Number of bit errors detected
%FFE or VNLE
[eq_signal,eq_noise] = EQ.process(rx_signal,tx_symbols);
% M = numel(unique(tx_symbols.signal));
rx_bits = PAMmapper(M,0).demap(eq_signal);
[~,numErrors,ber,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
end

View File

@@ -1,4 +1,18 @@
function vnle_postfilter_mlse()
function [eq_signal,eq_noise,ber,numErrors] = vnle_postfilter_mlse(eq_,pf_,mlse_,M,rx_signal,tx_symbols,tx_bits)
%FFE or VNLE
[eq_signal,eq_noise] = eq_.process(rx_signal,tx_symbols);
eq_signal = pf_.process(eq_signal,eq_noise);
%M = numel(unique(tx_symbols.signal));
mlse_.DIR = pf_.burg_coeff;
mlse_.trellis_states = PAMmapper(M,0).levels;
mlse_.M = M;
eq_signal = mlse_.process(eq_signal);
rx_bits = PAMmapper(M,0).demap(eq_signal);
[~,numErrors,ber,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
end

View File

@@ -1,5 +1,8 @@
function showCurrentMeasurement(varargin)
% showCurrentMeasurement displays measurement data in a figure with variable names
% USEFUL FOR LAB!
% showCurrentMeasurement displays lab measurement data in a table figure with variable names
% as column headers and values listed below. Calling the function multiple times
% with the same variable names but different values adds more data points.
%

View File

@@ -1,260 +0,0 @@
%CBREWER2 Interpolated versions of Cynthia Brewer's ColorBrewer colormaps
% CBREWER2(CNAME, NCOL) returns the colour scheme CNAME with the number
% of colours equal to NCOL. If there is a ColorBrewer scheme with exactly
% this number of colours, the color scheme is returned as-is. If NCOL
% larger (or smaller) than the designed colormaps for this scheme, the
% largest (smallest) one is interpolated to provide enough colours,
% unless the requested colour scheme CNAME is a qualitative palette. For
% a qualitative scheme, the colours are repeated, cycling from the
% beginning again, to output the requested NCOL colours.
%
% CBREWER2(CNAME) without an NCOL input will use the same number of
% colours as the current colormap.
%
% CBREWER2(CNAME, NCOL, INTERP_METHOD) allows you to change the method
% used for the interpolation. The default is 'cubic'.
%
% CBREWER2(CNAME, NCOL, INTERP_METHOD, INTERP_SPACE) allows you to
% change the colorspace used for the interpolation. By default, this is
% in the CIELAB colorspace, which is approximately perceptually uniform.
% Options for INTERP_SPACE are
% 'rgb' : interpolation in sRGB (as used in original CBREWER)
% 'lab' : interpolation in CIELAB (default)
% 'lch' : interpolation in CIELCH_ab (not recommended due to the
% discontinuities at C=0 and H=0)
% Anything else supported by COLORSPACE will also function.
%
% The input format CBREWER2(TYPE, ...) can also be used, where TYPE is
% one of 'seq', 'div', 'qual'. This input is redandant and will be
% ignored. This input format is provided for backwards compatibility with
% the original CBREWER.
%
% Example 1 (sequential heatmap):
% C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
% imagesc(C);
% colorbar;
% colormap(cbrewer('YlOrRd', 256);
%
% Example 2 (line plot):
% x = 0:0.01:2;
% sc = [0.5; 1; 2];
% t0 = [0; 0.2; 0.4];
% t = bsxfun(@rdivide, bsxfun(@plus, x, t0), sc);
% y = sin(t * 2 * pi);
% cmap = cbrewer2('Set1', numel(sc));
% axes('ColorOrder', cmap, 'NextPlot', 'ReplaceChildren');
% plot(x, y);
%
% Example 3 (divergent heatmap):
% [X,Y,Z] = peaks(30);
% surfc(X,Y,Z);
% colormap(cbrewer2('RdBu'));
%
% This product includes color specifications and designs developed by
% Cynthia Brewer (http://colorbrewer.org/). For more information on
% ColorBrewer, please visit http://colorbrewer.org/.
%
% CBREWER2 uses a cached copy of the Cynthia Brewer color schemes which
% was converted to .mat format by Charles Robert for use with CBREWER.
% CBREWER is available from the MATLAB FileExchange under the MIT license.
%
% See also CBREWER, BREWERMAP, COLORSPACE, INTERP1.
% Copyright (c) 2016 Scott Lowe
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
function colormap = cbrewer2(...
cname, ncol, interp_method, interp_space, varargin)
% Definitions -------------------------------------------------------------
% List of all of Cynthia Brewer's colormaps and their types
% seq: sequential
% div: divergent
% qual: qualitative
cbdict = {...
'Blues', 'seq'; ...
'BuGn', 'seq'; ...
'BuPu', 'seq'; ...
'GnBu', 'seq'; ...
'Greens', 'seq'; ...
'Greys', 'seq'; ...
'Oranges', 'seq'; ...
'OrRd', 'seq'; ...
'PuBu', 'seq'; ...
'PuBuGn', 'seq'; ...
'PuRd', 'seq'; ...
'Purples', 'seq'; ...
'RdPu', 'seq'; ...
'Reds', 'seq'; ...
'YlGn', 'seq'; ...
'YlGnBu', 'seq'; ...
'YlOrBr', 'seq'; ...
'YlOrRd', 'seq'; ...
'BrBG', 'div'; ...
'PiYG', 'div'; ...
'PRGn', 'div'; ...
'PuOr', 'div'; ...
'RdBu', 'div'; ...
'RdGy', 'div'; ...
'RdYlBu', 'div'; ...
'RdYlGn', 'div'; ...
'Spectral', 'div'; ...
'Accent', 'qual'; ...
'Dark2', 'qual'; ...
'Paired', 'qual'; ...
'Pastel1', 'qual'; ...
'Pastel2', 'qual'; ...
'Set1', 'qual'; ...
'Set2', 'qual'; ...
'Set3', 'qual'; ...
};
% Input handling ----------------------------------------------------------
narginchk(1, 5);
% Initialise variables if not supplied
if nargin<2
ncol = [];
end
if nargin<3
interp_method = [];
end
if nargin<4
interp_space = [];
end
if nargin<5
varargin = {[]};
end
% Check if the colormap type was unnecessarily input
types = unique(cbdict(:, 2));
if nargin > 1 && ischar(cname) && ischar(ncol)
LI = ismember({cname ncol}, types);
if ~any(LI); error('Number of colors cannot be a string'); end;
if all(LI); error('Incorrect colormap name'); end;
if LI(1)
vgn = {cname; ncol; interp_method; interp_space};
cname = vgn{2};
ncol = vgn{3};
interp_method = vgn{4};
interp_space = varargin{1};
ctype_input = vgn{1};
elseif LI(2)
vgn = {cname; ncol; interp_method; interp_space};
cname = vgn{1};
ncol = vgn{3};
interp_method = vgn{4};
interp_space = varargin{1};
ctype_input = vgn{2};
end
else
ctype_input = '';
end
% Default values
if isempty(ncol)
% Number of colours in the colormap
ncol = size(get(gcf,'colormap'), 1);
end
if isempty(interp_method)
interp_method = 'pchip';
end
if isempty(interp_space)
interp_space = 'lab';
end
% Load colorbrewer data ---------------------------------------------------
Tmp = load('colorbrewer.mat');
colorbrewer = Tmp.colorbrewer;
[TF, idict] = ismember(lower(cname), lower(cbdict(:, 1)));
if ~TF
error('%s is not a recognised Brewer colormap',cname);
end
cname = cbdict{idict, 1};
ctype = cbdict{idict, 2};
if (~isfield(colorbrewer.(ctype), cname))
error('Colormap %s is not present in loaded data',cname);
end
% Main script -------------------------------------------------------------
if ncol > length(colorbrewer.(ctype).(cname))
% If we specified too many colours, we take the maximum and interpolate
colormap = colorbrewer.(ctype).(cname){length(colorbrewer.(ctype).(cname))};
colormap = colormap ./ 255;
elseif isempty(colorbrewer.(ctype).(cname){ncol})
% If we specified too few colours, we take the minimum and interpolate
nmin = find(~cellfun(@isempty, colorbrewer.(ctype).(cname)), 1);
colormap = colorbrewer.(ctype).(cname){nmin};
colormap = colormap./255;
else
% If we specified a number of colours in the pre-designed range, no
% need to interpolate
colormap = (colorbrewer.(ctype).(cname){ncol}) ./ 255;
return;
end
% Don't interpolate if qualitative type
if strcmp(ctype,'qual')
if size(colormap, 1) >= ncol
colormap = colormap(1:ncol, :);
return;
end
warning('CBREWER2:QualTooManyColors', ...
['Too many colors requested: cannot interpolate a qualitative' ...
' colorscheme']);
% Cycle the colours from the beginning again, so we have enough to
% return
colormap = repmat(colormap, ceil(ncol / size(colormap, 1)), 1);
colormap = colormap(1:ncol, :);
return;
end
% Make sure we have colorspace downloaded from the FEX
if ~strcmpi(interp_space, 'rgb') && ~exist('colorspace.m', 'file')
P = requireFEXpackage(28790);
if isempty(P);
error(...
['You need to download COLORSPACE from the MATLAB FEX and' ...
' add it to the MATLAB path.']);
end;
end
% Move to perceptually uniform space
if ~strcmpi(interp_space,'rgb')
colormap = colorspace(['rgb->' interp_space], colormap);
end
% Linearly interpolate
X = linspace(0, 1, size(colormap, 1));
XI = linspace(0, 1, ncol);
colormap = interp1(X, colormap, XI, interp_method);
% Move from perceptually uniform space back to sRGB
if ~strcmpi(interp_space,'rgb')
colormap = colorspace(['rgb<-' interp_space], colormap);
end
end

View File

@@ -1,194 +0,0 @@
function AddedPath = requireFEXpackage(FEXSubmissionID)
%Function requireFEXpackage -
%installs Matlab Central File Exchange (FEX) submission
%with given ID into the directory chosen by the user.
%A new FEX submissions may use previous FEX submissions as its part.
%The function 'requireFEXpackage' helps in adding those previous
%submissions to the user's MATLAB installation.
%
%This function is a part of File Exchange submission 31069.
%Download the entire submission:
%http://www.mathworks.com/matlabcentral/fileexchange/31069
%
% SYNTAX:
% AddedPath = requireFEXpackage(FEXSubmissionID)
%
% INPUT:
% ID of the required submission to File Exchange
%
% OUTPUT:
% the path to that submission added to the user's MATLAB path.
%
% HOW TO CALL:
% The command
% P = requireFEXpackage(8277)
% will download and install the package with ID 8277
% (namely, nice 'fminsearchbnd' by John D'Errico)
%
% EXAMPLES -- HOW TO USE:
%
% EXAMPLE 1 (using 'exist' command):
%
% % first, somewhere in the very beginning of your code,
% % check if the function 'fminsearchbnd' from the FEX package 8277
% % is on your MATLAB path, and if it is not there,
% % require the FEX package 8277:
% if ~(exist('fminsearchbnd', 'file') == 2)
% P = requireFEXpackage(8277); % fminsearchbnd is part of 8277
% end
%
% % Then just use 'fminsearchbnd' where you need it:
% syms x
% RosenbrockBananaFunction = @(x) (1-x(1)).^2 + 100*(x(2)-x(1).^2).^2;
% x = fminsearchbnd(RosenbrockBananaFunction,[3 3])
% EXAMPLE 2 (using 'try-catch' command):
%
% syms x
% RosenbrockBananaFunction = @(x) (1-x(1)).^2+100*(x(2)-x(1).^2).^2;
% try
% % if function 'fminsearchbnd' already exists in your MATLAB
% % installation, just use it:
% x = fminsearchbnd(RosenbrockBananaFunction,[3 3])
% catch
% % if function 'fminsearchbnd' is not present in your MATLAB
% % installation, first get the package 8277 (to which it belongs)
% % from the MATLAB Central File Exchange (FEX)
% P = requireFEXpackage(8277); % fminsearchbnd is part of 8277
% % and then use that function:
% x = fminsearchbnd(RosenbrockBananaFunction,[3 3])
% end
%
%
% NOTE: on Mac platform, the title of the dialog box for
% choosing the directory for installing the required FEX package
% is not shown; this is not a bug, this is how UIGETDIR works on Macs --
% see the documentation for UIGETDIR
% http://www.mathworks.com/help/techdoc/ref/uigetdir.html
%
% (C) Igor Podlubny, 2011
% Copyright (c) 2011, Igor Podlubny
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in
% the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
ID = num2str(FEXSubmissionID);
% Ask user for the confirmation of the installation
% of the required FEX package
yes = ['YES, Install package ' ID];
no = 'NO, do not install';
userchoice = questdlg(['The Matlab function/toolbox, which you are running, ' ...
'requires the presence of the package ' ID ...
' from Matlab Central File Exchange.' ...
sprintf('\n\n') ...
'Would you like to install the FEX package ' ID ' now?'] , ...
['Required package ' ID], ...
yes, no, yes);
% Handle response
switch userchoice
case yes,
install = 1;
case no,
install = 0;
otherwise,
install = 0;
end
if install == 1
baseURL = 'http://www.mathworks.com/matlabcentral/fileexchange/';
query = '?download=true';
location = uigetdir(pwd, ['Select the directory for installing the required FEX package' ID ]);
if location ~= 0
% download package 'ID' from Matlab Central File Exchange
filetosave = [location filesep ID '.zip'];
FEXpackage = [baseURL ID query];
[f,status] = urlwrite(FEXpackage,filetosave);
if status==0
warndlg(['No connection to Matlab Central File Exchange,' ' or package ' ID ' does not exist.' ...
' Package ' ID ' has not been installed. ' ...
' Check you internet settings and the ID of the required package, and try again. '] , ...
['No connection to Matlab Central File Exchange' ' or package ' ID ' does not exist'], ...
'modal');
AddedPath = '';
return
end
% unzip the downloaded file to the subdirectory 'ID'
todir = [location filesep ID];
% if the directory 'ID' doesn't exist at given location, create it
if ~(exist([location filesep ID], 'dir') == 7)
mkdir(location, ID);
end
try
unzip(filetosave, todir);
% after unzipping, delete the downloaded ZIP file
delete(filetosave);
% prepend the paths to the downloaded package to the MATLAB path
P = genpath([location filesep ID]);
path(P,path);
catch
% if the FEX package is not ZIP, then it is a single m-file
% just move the file to the ID directory
[pathstr, name, ext] = fileparts(filetosave);
movefile(filetosave, [todir filesep name '.m']);
P = genpath([location filesep ID]);
path(P,path);
end
else
P = '';
end
AddedPath = P;
else
AddedPath = '';
end
if install == 1,
% Ask user about reviewing and saving the modified MATLAB path,
% and take him to PATHTOOL, if the user wants to save the modified path
yes = 'YES, I want to review and save the MATLAB path';
no = 'NO, I don''t want to save the path permanently';
userchoice = questdlg(['After adding the package ' ID ...
' from Matlab Central File Exchange to your MATLAB installation,' ...
' the MATLAB path has been modified accordingly. ', ...
'Would you like to review and save the modified MATLAB path?'] , ...
'Review and save the modified MATLAB path for future use?', ...
yes, no, yes);
% Handle response
switch userchoice
case yes,
pathtool;
case no,
otherwise,
end
end

View File

@@ -1,261 +0,0 @@
% function lineStyles = linspecer(N)
% This function creates an Nx3 array of N [R B G] colors
% These can be used to plot lots of lines with distinguishable and nice
% looking colors.
%
% lineStyles = linspecer(N); makes N colors for you to use: lineStyles(ii,:)
%
% colormap(linspecer); set your colormap to have easily distinguishable
% colors and a pleasing aesthetic
%
% lineStyles = linspecer(N,'qualitative'); forces the colors to all be distinguishable (up to 12)
% lineStyles = linspecer(N,'sequential'); forces the colors to vary along a spectrum
%
% % Examples demonstrating the colors.
%
% LINE COLORS
% N=6;
% X = linspace(0,pi*3,1000);
% Y = bsxfun(@(x,n)sin(x+2*n*pi/N), X.', 1:N);
% C = linspecer(N);
% axes('NextPlot','replacechildren', 'ColorOrder',C);
% plot(X,Y,'linewidth',5)
% ylim([-1.1 1.1]);
%
% SIMPLER LINE COLOR EXAMPLE
% N = 6; X = linspace(0,pi*3,1000);
% C = linspecer(N)
% hold off;
% for ii=1:N
% Y = sin(X+2*ii*pi/N);
% plot(X,Y,'color',C(ii,:),'linewidth',3);
% hold on;
% end
%
% COLORMAP EXAMPLE
% A = rand(15);
% figure; imagesc(A); % default colormap
% figure; imagesc(A); colormap(linspecer); % linspecer colormap
%
% See also NDHIST, NHIST, PLOT, COLORMAP, 43700-cubehelix-colormaps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% by Jonathan Lansey, March 2009-2013 Lansey at gmail.com %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% credits and where the function came from
% The colors are largely taken from:
% http://colorbrewer2.org and Cynthia Brewer, Mark Harrower and The Pennsylvania State University
%
%
% She studied this from a phsychometric perspective and crafted the colors
% beautifully.
%
% I made choices from the many there to decide the nicest once for plotting
% lines in Matlab. I also made a small change to one of the colors I
% thought was a bit too bright. In addition some interpolation is going on
% for the sequential line styles.
%
%
%%
function lineStyles=linspecer(N,varargin)
if nargin==0 % return a colormap
lineStyles = linspecer(128);
return;
end
if ischar(N)
lineStyles = linspecer(128,N);
return;
end
if N<=0 % its empty, nothing else to do here
lineStyles=[];
return;
end
% interperet varagin
qualFlag = 0;
colorblindFlag = 0;
if ~isempty(varargin)>0 % you set a parameter?
switch lower(varargin{1})
case {'qualitative','qua'}
if N>12 % go home, you just can't get this.
warning('qualitiative is not possible for greater than 12 items, please reconsider');
else
if N>9
warning(['Default may be nicer for ' num2str(N) ' for clearer colors use: whitebg(''black''); ']);
end
end
qualFlag = 1;
case {'sequential','seq'}
lineStyles = colorm(N);
return;
case {'white','whitefade'}
lineStyles = whiteFade(N);return;
case 'red'
lineStyles = whiteFade(N,'red');return;
case 'blue'
lineStyles = whiteFade(N,'blue');return;
case 'green'
lineStyles = whiteFade(N,'green');return;
case {'gray','grey'}
lineStyles = whiteFade(N,'gray');return;
case {'colorblind'}
colorblindFlag = 1;
otherwise
warning(['parameter ''' varargin{1} ''' not recognized']);
end
end
% *.95
% predefine some colormaps
set3 = colorBrew2mat({[141, 211, 199];[ 255, 237, 111];[ 190, 186, 218];[ 251, 128, 114];[ 128, 177, 211];[ 253, 180, 98];[ 179, 222, 105];[ 188, 128, 189];[ 217, 217, 217];[ 204, 235, 197];[ 252, 205, 229];[ 255, 255, 179]}');
set1JL = brighten(colorBrew2mat({[228, 26, 28];[ 55, 126, 184]; [ 77, 175, 74];[ 255, 127, 0];[ 255, 237, 111]*.85;[ 166, 86, 40];[ 247, 129, 191];[ 153, 153, 153];[ 152, 78, 163]}'));
set1 = brighten(colorBrew2mat({[ 55, 126, 184]*.85;[228, 26, 28];[ 77, 175, 74];[ 255, 127, 0];[ 152, 78, 163]}),.8);
% colorblindSet = {[215,25,28];[253,174,97];[171,217,233];[44,123,182]};
colorblindSet = {[215,25,28];[253,174,97];[171,217,233]*.8;[44,123,182]*.8};
set3 = dim(set3,.93);
if colorblindFlag
switch N
% sorry about this line folks. kind of legacy here because I used to
% use individual 1x3 cells instead of nx3 arrays
case 4
lineStyles = colorBrew2mat(colorblindSet);
otherwise
colorblindFlag = false;
warning('sorry unsupported colorblind set for this number, using regular types');
end
end
if ~colorblindFlag
switch N
case 1
lineStyles = { [ 55, 126, 184]/255};
case {2, 3, 4, 5 }
lineStyles = set1(1:N);
case {6 , 7, 8, 9}
lineStyles = set1JL(1:N)';
case {10, 11, 12}
if qualFlag % force qualitative graphs
lineStyles = set3(1:N)';
else % 10 is a good number to start with the sequential ones.
lineStyles = cmap2linspecer(colorm(N));
end
otherwise % any old case where I need a quick job done.
lineStyles = cmap2linspecer(colorm(N));
end
end
lineStyles = cell2mat(lineStyles);
end
% extra functions
function varIn = colorBrew2mat(varIn)
for ii=1:length(varIn) % just divide by 255
varIn{ii}=varIn{ii}/255;
end
end
function varIn = brighten(varIn,varargin) % increase the brightness
if isempty(varargin),
frac = .9;
else
frac = varargin{1};
end
for ii=1:length(varIn)
varIn{ii}=varIn{ii}*frac+(1-frac);
end
end
function varIn = dim(varIn,f)
for ii=1:length(varIn)
varIn{ii} = f*varIn{ii};
end
end
function vOut = cmap2linspecer(vIn) % changes the format from a double array to a cell array with the right format
vOut = cell(size(vIn,1),1);
for ii=1:size(vIn,1)
vOut{ii} = vIn(ii,:);
end
end
%%
% colorm returns a colormap which is really good for creating informative
% heatmap style figures.
% No particular color stands out and it doesn't do too badly for colorblind people either.
% It works by interpolating the data from the
% 'spectral' setting on http://colorbrewer2.org/ set to 11 colors
% It is modified a little to make the brightest yellow a little less bright.
function cmap = colorm(varargin)
n = 100;
if ~isempty(varargin)
n = varargin{1};
end
if n==1
cmap = [0.2005 0.5593 0.7380];
return;
end
if n==2
cmap = [0.2005 0.5593 0.7380;
0.9684 0.4799 0.2723];
return;
end
frac=.95; % Slight modification from colorbrewer here to make the yellows in the center just a bit darker
cmapp = [158, 1, 66; 213, 62, 79; 244, 109, 67; 253, 174, 97; 254, 224, 139; 255*frac, 255*frac, 191*frac; 230, 245, 152; 171, 221, 164; 102, 194, 165; 50, 136, 189; 94, 79, 162];
x = linspace(1,n,size(cmapp,1));
xi = 1:n;
cmap = zeros(n,3);
for ii=1:3
cmap(:,ii) = pchip(x,cmapp(:,ii),xi);
end
cmap = flipud(cmap/255);
end
function cmap = whiteFade(varargin)
n = 100;
if nargin>0
n = varargin{1};
end
thisColor = 'blue';
if nargin>1
thisColor = varargin{2};
end
switch thisColor
case {'gray','grey'}
cmapp = [255,255,255;240,240,240;217,217,217;189,189,189;150,150,150;115,115,115;82,82,82;37,37,37;0,0,0];
case 'green'
cmapp = [247,252,245;229,245,224;199,233,192;161,217,155;116,196,118;65,171,93;35,139,69;0,109,44;0,68,27];
case 'blue'
cmapp = [247,251,255;222,235,247;198,219,239;158,202,225;107,174,214;66,146,198;33,113,181;8,81,156;8,48,107];
case 'red'
cmapp = [255,245,240;254,224,210;252,187,161;252,146,114;251,106,74;239,59,44;203,24,29;165,15,21;103,0,13];
otherwise
warning(['sorry your color argument ' thisColor ' was not recognized']);
end
cmap = interpomap(n,cmapp);
end
% Eat a approximate colormap, then interpolate the rest of it up.
function cmap = interpomap(n,cmapp)
x = linspace(1,n,size(cmapp,1));
xi = 1:n;
cmap = zeros(n,3);
for ii=1:3
cmap(:,ii) = pchip(x,cmapp(:,ii),xi);
end
cmap = (cmap/255); % flipud??
end

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Some files were not shown because too many files have changed in this diff Show More