├── .gitattributes ├── LICENSE ├── MIToolbox-master ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── include │ └── MIToolbox │ │ ├── ArrayOperations.h │ │ ├── CalculateProbability.h │ │ ├── Entropy.h │ │ ├── MIToolbox.h │ │ ├── MutualInformation.h │ │ ├── RenyiEntropy.h │ │ ├── RenyiMutualInformation.h │ │ ├── WeightedEntropy.h │ │ └── WeightedMutualInformation.h ├── matlab │ ├── CompileMIToolbox.m │ ├── MIToolbox.m │ ├── MIToolboxMex.c │ ├── RenyiMIToolbox.m │ ├── RenyiMIToolboxMex.c │ ├── WeightedMIToolbox.m │ ├── WeightedMIToolboxMex.c │ ├── cmi.m │ ├── condh.m │ ├── demonstration_algorithms │ │ ├── CMIM.m │ │ ├── CMIM_Mex.c │ │ ├── CompileDemos.m │ │ ├── DISR.m │ │ ├── DISR_Mex.c │ │ ├── IAMB.m │ │ ├── mRMR_D.m │ │ └── mRMR_D_Mex.c │ ├── h.m │ ├── joint.m │ └── mi.m ├── src │ ├── ArrayOperations.c │ ├── CalculateProbability.c │ ├── Entropy.c │ ├── MutualInformation.c │ ├── RenyiEntropy.c │ ├── RenyiMutualInformation.c │ ├── WeightedEntropy.c │ └── WeightedMutualInformation.c └── test │ └── testMIToolbox.c ├── MI_of_norm.m ├── OFDM-ray-exp ├── ambc_ofdm_ray_exe.m ├── data_input.txt ├── func_ambc_ofdm_ray_exe.m ├── func_ambc_ofdm_ray_exe_02.m ├── mi_p.m ├── mi_p.mat └── readme.md ├── OFDM ├── Picture1.bmp ├── ambc_ofdm.m ├── ambc_ofdm_02.m ├── ambc_ofdm_03.m ├── ofdm_sim.m └── readme.md ├── entropy_of_norm.m ├── ken-gen-sim-02 ├── c_g1_02.m ├── c_h12_02.m ├── c_p_02.m ├── c_rho_02.m ├── key_gen_func_02.m └── test_func02.m ├── ken-gen-sim-1 ├── c_p.m ├── c_rho.m └── key_gen_func.m ├── mi_BC_system_h12_cons.m ├── mi_BC_system_h12_norm.m ├── mi_variables.m ├── readme.md ├── sim07 ├── ambc_ofdm.m ├── ambc_ofdm_eve.m ├── data_input.txt ├── eave_ray_model.m ├── evea_design.m ├── mi_dist.m ├── mi_snr.m ├── ofdm_back.m ├── ofdm_module.m ├── ofdm_trans.m ├── plot_mi_bdr.m ├── plot_mi_dist.m ├── plot_mi_eth.m ├── plot_skr.m ├── ray_model.m ├── readme.md ├── receiver_design.m ├── skr_snr.m ├── skr_snr_trad.m └── test_corr.m └── sim08 ├── Jakes_Flat.m ├── ambc_ofdm.m ├── ambc_ofdm_eve.m ├── data_input.txt ├── eave_ray_model.m ├── evea_design.m ├── mi_dist.m ├── mi_snr.m ├── mi_snr2.m ├── mi_snr_ne.m ├── mi_snr_ne2.m ├── mi_snr_ne_trad.m ├── mi_snr_ne_trad2.m ├── ofdm_back.m ├── ofdm_module.m ├── ofdm_trans.m ├── plot_mi_bdr.m ├── plot_mi_bdr_ne.m ├── plot_mi_bdr_preamble.m ├── plot_mi_dist.m ├── plot_mi_eth.m ├── plot_skr.m ├── ray_model.m ├── ray_model_cor.m ├── readme.md ├── receiver_design.m ├── receiver_design2.m ├── skr_snr.m ├── skr_snr_50000.mat ├── skr_snr_trad.m └── test_corr.m /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /MIToolbox-master/.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | 5 | # Libraries 6 | *.lib 7 | *.a 8 | 9 | # Shared objects (inc. Windows DLLs) 10 | *.dll 11 | *.so 12 | *.so.* 13 | *.dylib 14 | 15 | # Executables 16 | *.exe 17 | *.out 18 | *.app 19 | 20 | # Matlab/Octave executables 21 | *.mex* 22 | *.oct* 23 | 24 | # Editor backups 25 | *~ 26 | 27 | # Build folder 28 | /build/ -------------------------------------------------------------------------------- /MIToolbox-master/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2010-2017, Adam Pocock, The University of Manchester 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /MIToolbox-master/Makefile: -------------------------------------------------------------------------------- 1 | #makefile for MIToolbox 2 | #Author: Adam Pocock, apocock@cs.man.ac.uk 3 | #Created 11/03/2010 4 | #Updated 22/02/2014 - Added make install 5 | #Updated 05/09/2016 - Repackaging 6 | # 7 | # 8 | #Copyright 2010-2017 Adam Pocock, The University Of Manchester 9 | #www.cs.manchester.ac.uk 10 | # 11 | #This file is part of MIToolbox, licensed under the 3-clause BSD license. 12 | 13 | PREFIX = /usr/local 14 | CFLAGS = -O3 -fPIC -std=c89 -pedantic -Wall -Werror 15 | INCLUDES = -Iinclude 16 | CC = gcc 17 | objects = build/ArrayOperations.o build/CalculateProbability.o \ 18 | build/Entropy.o build/MutualInformation.o \ 19 | build/RenyiEntropy.o build/RenyiMutualInformation.o \ 20 | build/WeightedEntropy.o build/WeightedMutualInformation.o 21 | 22 | libMIToolbox.so : $(objects) 23 | $(CC) $(CFLAGS) -shared -o libMIToolbox.so $(objects) -lm 24 | 25 | libMIToolbox.dll : $(objects) 26 | $(CC) -shared -o libMIToolbox.dll $(objects) -lm 27 | 28 | build/%.o: src/%.c 29 | @mkdir -p build 30 | $(CC) $(CFLAGS) $(INCLUDES) -DCOMPILE_C -o build/$*.o -c $< 31 | 32 | .PHONY : debug x86 x64 matlab matlab-debug intel install test 33 | debug: 34 | $(MAKE) libMIToolbox.so "CFLAGS = -g -DDEBUG -fPIC" 35 | 36 | x86: 37 | $(MAKE) libMIToolbox.so "CFLAGS = -O3 -fPIC -m32" 38 | 39 | x64: 40 | $(MAKE) libMIToolbox.so "CFLAGS = -O3 -fPIC -m64" 41 | 42 | x64_win: 43 | $(MAKE) libMIToolbox.dll "CFLAGS = -O3 -m64" 44 | 45 | intel: 46 | $(MAKE) libMIToolbox.so "CC = icc" "CFLAGS = -O2 -fPIC -xHost" 47 | 48 | clean: 49 | -rm -fr build 50 | -rm -f matlab/*.o matlab/*.mex* 51 | -rm -f libMIToolbox.so 52 | -rm -f libMIToolbox.dll 53 | 54 | install: libMIToolbox.so 55 | @echo "Installing libMIToolbox.so to $(PREFIX)/lib" 56 | @cp -v libMIToolbox.so $(PREFIX)/lib 57 | @mkdir -p $(PREFIX)/include 58 | @echo "Installing MIToolbox's header files to $(PREFIX)/include/MIToolbox" 59 | @cp -rv include/MIToolbox $(PREFIX)/include/ 60 | 61 | test: 62 | $(CC) -std=c89 $(INCLUDES) -L. -o test.out test/testMIToolbox.c -lMIToolbox 63 | -------------------------------------------------------------------------------- /MIToolbox-master/README.md: -------------------------------------------------------------------------------- 1 | MIToolbox 2 | ========= 3 | v3.0.1 for C/C++ and MATLAB/Octave 4 | 5 | MIToolbox contains a set of functions to calculate information theoretic 6 | quantities from data, such as the entropy and mutual information. The toolbox 7 | contains implementations of the most popular Shannon entropies, and also the 8 | lesser known Renyi entropy. The toolbox also provides implementations of 9 | the weighted entropy and weighted mutual information from "Information Theory 10 | with Application", S. Guiasu (1977). The toolbox only supports discrete distributions, 11 | as opposed to continuous. All real-valued numbers will be processed by x = floor(x). 12 | 13 | These functions are targeted for use with feature selection algorithms rather 14 | than communication channels and so expect all the data to be available before 15 | execution and sample their own probability distributions from the data. 16 | 17 | All functions expect the inputs to be vectors or matrices of doubles. 18 | 19 | Functions contained: 20 | - Entropy 21 | - Conditional Entropy 22 | - Mutual Information 23 | - Conditional Mutual Information 24 | - generating a joint variable 25 | - generating a probability distribution from a discrete random variable 26 | - Renyi's Entropy 27 | - Renyi's Mutual Information 28 | - Weighted Entropy 29 | - Weighted Mutual Information 30 | - Weighted Conditional Mutual Information 31 | 32 | Note: all functions are calculated in log base 2, so return units of "bits". 33 | 34 | MIToolbox works on discrete inputs, and all continuous values **must** be 35 | discretised before use with MIToolbox. Real-valued inputs will be discretised 36 | with x = floor(x) to ensure compatibility. MIToolbox produces unreliable 37 | results when used with continuous inputs, runs slowly and uses much more memory 38 | than usual. The discrete inputs should have small cardinality, MIToolbox will 39 | treat values {1,10,100} the same way it treats {1,2,3} and the latter will be 40 | both faster and use less memory. This limitation is due to the difficulties in 41 | estimating information theoretic functions of continuous variables. 42 | 43 | ====== 44 | 45 | Examples: 46 | 47 | ``` 48 | >> y = [1 1 1 0 0]'; 49 | >> x = [1 0 1 1 0]'; 50 | ``` 51 | ``` 52 | >> mi(x,y) %% mutual information I(X;Y) 53 | ans = 54 | 0.0200 55 | ``` 56 | ``` 57 | >> h(x) %% entropy H(X) 58 | ans = 59 | 0.9710 60 | ``` 61 | ``` 62 | >> condh(x,y) %% conditional entropy H(X|Y) 63 | ans = 64 | 0.9510 65 | ``` 66 | ``` 67 | >> h( [x,y] ) %% joint entropy H(X,Y) 68 | ans = 69 | 1.9219 70 | ``` 71 | ``` 72 | >> joint([x,y]) %% joint random variable XY 73 | ans = 74 | 1 75 | 2 76 | 1 77 | 3 78 | 4 79 | ``` 80 | ====== 81 | 82 | All code is licensed under the 3-clause BSD license. 83 | 84 | Compilation instructions: 85 | - MATLAB/OCTAVE 86 | - run `CompileMIToolbox.m` from the `matlab` directory. 87 | - Linux C shared library 88 | - run `make x86` or `make x64` for 32-bit or 64-bit versions respectively. 89 | - run `sudo make install` to install MIToolbox into `/usr/local/lib` and `/usr/local/include` 90 | - Windows C dll 91 | - install MinGW from https://sourceforge.net/projects/mingw-w64/ 92 | - add MinGW binaries folders to PATH, e.g. `mingw/bin`, `mingw/msys/bin` 93 | - run `make x64_win` to compile a 64-bit Windows dll. 94 | 95 | Update History 96 | - 08/02/2017 - v3.0.1 - Bug fix to ensure ANSI C compatibility. 97 | - 07/01/2017 - v3.0.0 - Refactored internals to expose integer information theoretic calculations. 98 | - 10/01/2016 - v2.1.2 - Relicense from LGPL to BSD. Added checks to ensure input MATLAB types are doubles. 99 | - 02/02/2015 - v2.1.1 - Fixed up the Makefile so it installs the headers too. 100 | - 22/02/2014 - v2.1 - Fixed a couple of bugs related to memory handling. 101 | Added a make install for compatibility with PyFeast. 102 | - 30/07/2011 - v2.00 - Added implementations of the weighted entropy and weighted 103 | mutual information. More cleanup of Mex entry point 104 | to further check the inputs. 105 | - 08/11/2011 - v1.03 - Minor documentation changes to accompany the JMLR publication. 106 | - 15/10/2010 - v1.02 - Fixed bug where MIToolbox would cause a segmentation fault 107 | if a x by 0 empty matrix was passed in. Now prints an 108 | error message and returns gracefully. 109 | - 02/09/2010 - v1.01 - Fixed a bug in CMIM.m where the last feature would not be 110 | selected first if it had the highest MI. 111 | - 07/07/2010 - v1.00 - Initial Release. 112 | 113 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/ArrayOperations.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** ArrayOperations.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to floor arrays, and to merge arrays into a joint 6 | ** state. 7 | ** 8 | ** Author: Adam Pocock 9 | ** Created 17/2/2010 10 | ** Updated - 22/02/2014 - Added checking on calloc, and an increment array function. 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #ifndef __ArrayOperations_H 19 | #define __ArrayOperations_H 20 | 21 | #include "MIToolbox/MIToolbox.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | /******************************************************************************* 28 | ** A version of calloc which checks to see if memory was allocated. 29 | *******************************************************************************/ 30 | void* checkedCalloc(size_t vectorLength, size_t sizeOfType); 31 | 32 | /******************************************************************************* 33 | ** Increments each value in a double array 34 | *******************************************************************************/ 35 | void incrementVector(double* vector, int vectorLength); 36 | 37 | /******************************************************************************* 38 | ** Simple print functions for debugging 39 | *******************************************************************************/ 40 | void printDoubleVector(double *vector, int vectorlength); 41 | void printIntVector(int *vector, int vectorLength); 42 | void printUintVector(uint *vector, int vectorLength); 43 | 44 | /******************************************************************************* 45 | ** Generates a 2D representation of a contiguous fortran style matrix 46 | *******************************************************************************/ 47 | uint **generateIntIndices(uint *featureMatrix, uint noOfSamples, uint noOfFeatures); 48 | double **generateDoubleIndices(double *featureMatrix, uint noOfSamples, uint noOfFeatures); 49 | 50 | /******************************************************************************* 51 | ** Finds the maximum state of an int array. 52 | *******************************************************************************/ 53 | int maxState(uint* vector, int vectorLength); 54 | 55 | /******************************************************************************* 56 | ** numberOfUniqueValues finds the number of unique values in an array by 57 | ** repeatedly iterating through the array and checking if a value has been 58 | ** seen previously 59 | *******************************************************************************/ 60 | int numberOfUniqueValues(double *featureVector, int vectorLength); 61 | 62 | /******************************************************************************* 63 | ** normaliseArray takes an input vector and writes an output vector 64 | ** which is a normalised version of the input, and returns the number of states 65 | ** A normalised array has min value = 0, max value = number of states 66 | ** and all values are integers 67 | ** 68 | ** length(inputVector) == length(outputVector) == vectorLength otherwise there 69 | ** is a memory leak 70 | *******************************************************************************/ 71 | int normaliseArray(double *inputVector, uint *outputVector, int vectorLength); 72 | 73 | /******************************************************************************* 74 | ** mergeArrays takes in two arrays and writes the joint state of those arrays 75 | ** to the output vector 76 | ** 77 | ** the length of the vectors must be the same and equal to vectorLength 78 | *******************************************************************************/ 79 | int mergeArrays(uint *firstVector, uint *secondVector, uint *outputVector, int vectorLength); 80 | int discAndMergeArrays(double *firstVector, double *secondVector, uint *outputVector, int vectorLength); 81 | int mergeArraysArities(uint *firstVector, int numFirstStates, uint *secondVector, int numSecondStates, uint *outputVector, int vectorLength); 82 | int discAndMergeArraysArities(double *firstVector, int numFirstStates, double *secondVector, int numSecondStates, uint *outputVector, int vectorLength); 83 | 84 | /******************************************************************************* 85 | ** mergeMultipleArrays takes in a matrix and repeatedly merges the matrix using 86 | ** merge arrays and writes the joint state of that matrix 87 | ** to the output vector 88 | ** 89 | ** the length of the vectors must be the same and equal to vectorLength 90 | ** matrixWidth = the number of columns in the matrix 91 | *******************************************************************************/ 92 | int mergeMultipleArrays(double *inputMatrix, uint *outputVector, int matrixWidth, int vectorLength); 93 | int mergeMultipleArraysArities(double *inputMatrix, uint *outputVector, int matrixWidth, int *arities, int vectorLength); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/CalculateProbability.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** CalculateProbability.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the probability of each state in the array 6 | ** and to calculate the probability of the joint state of two arrays 7 | ** 8 | ** Author: Adam Pocock 9 | ** Created 17/2/2010 10 | ** 11 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 12 | ** www.cs.manchester.ac.uk 13 | ** 14 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 15 | *******************************************************************************/ 16 | 17 | #ifndef __CalculateProbability_H 18 | #define __CalculateProbability_H 19 | 20 | #include "MIToolbox/MIToolbox.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef struct jpState 27 | { 28 | double *jointProbabilityVector; 29 | int numJointStates; 30 | double *firstProbabilityVector; 31 | int numFirstStates; 32 | double *secondProbabilityVector; 33 | int numSecondStates; 34 | } JointProbabilityState; 35 | 36 | typedef struct pState 37 | { 38 | double *probabilityVector; 39 | int numStates; 40 | } ProbabilityState; 41 | 42 | typedef struct wjpState 43 | { 44 | double *jointProbabilityVector; 45 | double *jointWeightVector; 46 | int numJointStates; 47 | double *firstProbabilityVector; 48 | double *firstWeightVector; 49 | int numFirstStates; 50 | double *secondProbabilityVector; 51 | double *secondWeightVector; 52 | int numSecondStates; 53 | } WeightedJointProbState; 54 | 55 | typedef struct wpState 56 | { 57 | double *probabilityVector; 58 | double *stateWeightVector; 59 | int numStates; 60 | } WeightedProbState; 61 | 62 | /******************************************************************************* 63 | ** calculateJointProbability returns the joint probability vector of two vectors 64 | ** and the marginal probability vectors in a struct. 65 | ** It is the base operation for all information theory calculations involving 66 | ** two or more variables. 67 | ** 68 | ** length(firstVector) == length(secondVector) == vectorLength 69 | ** otherwise it will crash 70 | *******************************************************************************/ 71 | JointProbabilityState calculateJointProbability(uint *firstVector, uint *secondVector, int vectorLength); 72 | 73 | /******************************************************************************* 74 | ** discAndCalcJointProbability discretises the double vectors into int vectors, 75 | ** then generates a JointProbabilityState. 76 | ** 77 | ** length(firstVector) == length(secondVector) == vectorLength otherwise there 78 | ** will be a segmentation fault 79 | *******************************************************************************/ 80 | JointProbabilityState discAndCalcJointProbability(double *firstVector, double *secondVector, int vectorLength); 81 | 82 | /******************************************************************************* 83 | ** calculateWeightedJointProbability returns the same joint state object 84 | ** as calculateJointProbability, with additional weightVectors giving the 85 | ** weight assigned to each state. 86 | *******************************************************************************/ 87 | WeightedJointProbState calculateWeightedJointProbability(uint *firstVector, uint *secondVector, double *weightVector, int vectorLength); 88 | 89 | /******************************************************************************* 90 | ** discAndCalcWeightedJointProbability returns the same joint state object 91 | ** as discAndCalcJointProbability, with additional weightVectors giving the 92 | ** weight assigned to each state. 93 | *******************************************************************************/ 94 | WeightedJointProbState discAndCalcWeightedJointProbability(double *firstVector, double *secondVector, double *weightVector, int vectorLength); 95 | 96 | /******************************************************************************* 97 | ** calculateProbability returns the probability vector from one vector. 98 | ** It is the base operation for all information theory calculations involving 99 | ** one variable 100 | ** 101 | ** length(dataVector) == vectorLength otherwise there 102 | ** will be a segmentation fault 103 | *******************************************************************************/ 104 | ProbabilityState calculateProbability(uint *dataVector, int vectorLength); 105 | 106 | /******************************************************************************* 107 | ** discAndCalcProbability discretises the double vector into an int vector, 108 | ** then generates a ProbabilityState. 109 | ** 110 | ** length(dataVector) == vectorLength otherwise there 111 | ** will be a segmentation fault 112 | *******************************************************************************/ 113 | ProbabilityState discAndCalcProbability(double *dataVector, int vectorLength); 114 | 115 | /******************************************************************************* 116 | ** calculateWeightedProbability returns the same state object 117 | ** as calculateProbability, with an additional weightVector giving the 118 | ** weight assigned to each state. 119 | *******************************************************************************/ 120 | WeightedProbState calculateWeightedProbability(uint *dataVector, double *weightVector, int vectorLength); 121 | 122 | /******************************************************************************* 123 | ** discAndCalcWeightedProbability returns the same state object 124 | ** as discAndCalcProbability, with an additional weightVector giving the 125 | ** weight assigned to each state. 126 | *******************************************************************************/ 127 | WeightedProbState discAndCalcWeightedProbability(double *dataVector, double *weightVector, int vectorLength); 128 | 129 | /******************************************************************************* 130 | ** Frees the struct members and sets all pointers to NULL. 131 | *******************************************************************************/ 132 | void freeProbabilityState(ProbabilityState state); 133 | void freeJointProbabilityState(JointProbabilityState state); 134 | void freeWeightedProbState(WeightedProbState state); 135 | void freeWeightedJointProbState(WeightedJointProbState state); 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | 141 | #endif 142 | 143 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/Entropy.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** Entropy.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the entropy of a single variable H(X), 6 | ** the joint entropy of two variables H(X,Y), and the conditional entropy 7 | ** H(X|Y) 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 19/2/2010 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #ifndef __Entropy_H 19 | #define __Entropy_H 20 | 21 | #include "MIToolbox/MIToolbox.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /******************************************************************************* 29 | ** calculateEntropy returns the entropy in log base LOG_BASE of dataVector 30 | ** H(X) 31 | ** 32 | ** length(dataVector) == vectorLength otherwise there 33 | ** will be a segmentation fault 34 | *******************************************************************************/ 35 | double discAndCalcEntropy(double *dataVector, int vectorLength); 36 | double calcEntropy(uint *dataVector, int vectorLength); 37 | 38 | /******************************************************************************* 39 | ** calculateJointEntropy returns the entropy in log base LOG_BASE of the joint 40 | ** variable of firstVector and secondVector H(X,Y) 41 | ** 42 | ** length(firstVector) == length(secondVector) == vectorLength otherwise there 43 | ** will be a segmentation fault 44 | *******************************************************************************/ 45 | double discAndCalcJointEntropy(double *firstVector, double *secondVector, int vectorLength); 46 | double calcJointEntropy(uint *firstVector, uint *secondVector, int vectorLength); 47 | 48 | /******************************************************************************* 49 | ** calculateConditionalEntropy returns the entropy in log base LOG_BASE of dataVector 50 | ** conditioned on conditionVector, H(X|Y) 51 | ** 52 | ** length(dataVector) == length(conditionVector) == vectorLength otherwise there 53 | ** will be a segmentation fault 54 | *******************************************************************************/ 55 | double discAndCalcConditionalEntropy(double *dataVector, double *conditionVector, int vectorLength); 56 | double calcConditionalEntropy(uint *dataVector, uint *conditionVector, int vectorLength); 57 | 58 | /******************************************************************************* 59 | ** Inner functions which operate on state structs. 60 | *******************************************************************************/ 61 | double entropy(ProbabilityState state); 62 | double jointEntropy(JointProbabilityState state); 63 | double condEntropy(JointProbabilityState state); 64 | 65 | #ifdef __cplusplus 66 | } 67 | #endif 68 | 69 | #endif 70 | 71 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/MIToolbox.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** MIToolbox.h 3 | ** Provides the header files and #defines to ensure compatibility with MATLAB 4 | ** and C/C++. By default it compiles to MATLAB, if COMPILE_C is defined it 5 | ** links to the C memory allocation functions. 6 | ** 7 | ** Author: Adam Pocock 8 | ** Created: 17/2/2010 9 | ** Modified: 24/06/2011 - added log base #define 10 | ** 11 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 12 | ** www.cs.manchester.ac.uk 13 | ** 14 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 15 | *******************************************************************************/ 16 | 17 | #ifndef __MIToolbox_H 18 | #define __MIToolbox_H 19 | 20 | #include 21 | #include 22 | 23 | #define BASE_TWO 2.0 24 | #define BASE_E M_E 25 | 26 | #define LOG_BASE BASE_TWO 27 | 28 | typedef unsigned int uint; 29 | 30 | #ifdef COMPILE_C 31 | #define C_IMPLEMENTATION 32 | #include 33 | #include 34 | #define CALLOC_FUNC(a,b) calloc(a,b) 35 | #define FREE_FUNC(a) free(a) 36 | #elif defined(COMPILE_R) 37 | #define R_IMPLEMENTATION 38 | #include "R.h" 39 | #define CALLOC_FUNC(a,b) Calloc((a)*(b),char) 40 | #define FREE_FUNC(a) Free((a)) 41 | #define printf Rprintf 42 | #else 43 | #define MEX_IMPLEMENTATION 44 | #include "mex.h" 45 | #define CALLOC_FUNC(a,b) mxCalloc(a,b) 46 | #define FREE_FUNC(a) mxFree(a) 47 | #define printf mexPrintf /*for Octave-3.2*/ 48 | #endif 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/MutualInformation.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** MutualInformation.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the mutual information of 6 | ** two variables X and Y, I(X;Y), to calculate the joint mutual information 7 | ** of two variables X & Z on the variable Y, I(XZ;Y), and the conditional 8 | ** mutual information I(x;Y|Z) 9 | ** 10 | ** Author: Adam Pocock 11 | ** Created 19/2/2010 12 | ** 13 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 14 | ** www.cs.manchester.ac.uk 15 | ** 16 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 17 | *******************************************************************************/ 18 | 19 | #ifndef __MutualInformation_H 20 | #define __MutualInformation_H 21 | 22 | #include "MIToolbox/MIToolbox.h" 23 | #include "MIToolbox/CalculateProbability.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /******************************************************************************* 30 | ** calculateMutualInformation returns the log base LOG_BASE mutual information between 31 | ** dataVector and targetVector, I(X;Y) 32 | ** 33 | ** length(dataVector) == length(targetVector) == vectorLength otherwise there 34 | ** will be a segmentation fault 35 | *******************************************************************************/ 36 | double calcMutualInformation(uint *dataVector, uint *targetVector, int vectorLength); 37 | double discAndCalcMutualInformation(double *dataVector, double *targetVector, int vectorLength); 38 | 39 | /******************************************************************************* 40 | ** calculateConditionalMutualInformation returns the log base LOG_BASE 41 | ** mutual information between dataVector and targetVector, conditioned on 42 | ** conditionVector, I(X;Y|Z) 43 | ** 44 | ** length(dataVector) == length(targetVector) == length(condtionVector) == vectorLength 45 | ** otherwise it will error with a segmentation fault 46 | *******************************************************************************/ 47 | double calcConditionalMutualInformation(uint *dataVector, uint *targetVector, uint *conditionVector, int vectorLength); 48 | double discAndCalcConditionalMutualInformation(double *dataVector, double *targetVector, double *conditionVector, int vectorLength); 49 | 50 | /******************************************************************************* 51 | ** Inner functions which operate on state structs. 52 | *******************************************************************************/ 53 | double mi(JointProbabilityState state); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/RenyiEntropy.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** RenyiEntropy.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the Renyi alpha entropy of a single variable 6 | ** H_\alpha(X), the Renyi joint entropy of two variables H_\alpha(X,Y), and the 7 | ** conditional Renyi entropy H_\alpha(X|Y) 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 26/3/2010 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #ifndef __Renyi_Entropy_H 19 | #define __Renyi_Entropy_H 20 | 21 | #include "MIToolbox/MIToolbox.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /******************************************************************************* 29 | ** calculateRenyiEntropy returns the Renyi entropy in log base LOG_BASE of dataVector 30 | ** H_{\alpha}(X), for \alpha != 1 31 | ** 32 | ** length(dataVector) == vectorLength otherwise there 33 | ** will be a segmentation fault 34 | *******************************************************************************/ 35 | double calcRenyiEntropy(double alpha, uint *dataVector, int vectorLength); 36 | double discAndCalcRenyiEntropy(double alpha, double *dataVector, int vectorLength); 37 | 38 | /******************************************************************************* 39 | ** calculateJointRenyiEntropy returns the Renyi entropy in log base LOG_BASE of the 40 | ** joint variable of firstVector and secondVector H_{\alpha}(XY), 41 | ** for \alpha != 1 42 | ** 43 | ** length(firstVector) == length(secondVector) == vectorLength otherwise there 44 | ** will be a segmentation fault 45 | *******************************************************************************/ 46 | double calcJointRenyiEntropy(double alpha, uint *firstVector, uint *secondVector, int vectorLength); 47 | double discAndCalcJointRenyiEntropy(double alpha, double *firstVector, double *secondVector, int vectorLength); 48 | 49 | /******************************************************************************* 50 | ** Inner functions which operate on state structs. 51 | *******************************************************************************/ 52 | double renyiEntropy(ProbabilityState state, double alpha); 53 | double jointRenyiEntropy(JointProbabilityState state, double alpha); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/RenyiMutualInformation.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** RenyiMutualInformation.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the Renyi mutual information of 6 | ** two variables X and Y, I_\alpha(X;Y), using the Renyi alpha divergence and 7 | ** the joint entropy difference 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 26/3/2010 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #ifndef __Renyi_MutualInformation_H 19 | #define __Renyi_MutualInformation_H 20 | 21 | #include "MIToolbox/MIToolbox.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /******************************************************************************* 29 | ** calculateRenyiMIDivergence returns the log base LOG_BASE Renyi mutual information 30 | ** between dataVector and targetVector, I_{\alpha}(X;Y), for \alpha != 1 31 | ** This uses Renyi's generalised alpha divergence as the difference measure 32 | ** instead of the KL-divergence as in Shannon's Mutual Information 33 | ** 34 | ** length(dataVector) == length(targetVector) == vectorLength otherwise there 35 | ** will be a segmentation fault 36 | *******************************************************************************/ 37 | double calcRenyiMIDivergence(double alpha, uint *dataVector, uint *targetVector, int vectorLength); 38 | double discAndCalcRenyiMIDivergence(double alpha, double *dataVector, double *targetVector, int vectorLength); 39 | 40 | /****************************************************************************** 41 | ** This function returns a different value to the alpha divergence mutual 42 | ** information, and thus is not a correct mutual information. 43 | ** It is maintained to show how different Renyi's Information Theory is. 44 | ******************************************************************************/ 45 | double calcRenyiMIJoint(double alpha, uint *dataVector, uint *targetVector, int vectorLength); 46 | double discAndCalcRenyiMIJoint(double alpha, double *dataVector, double *targetVector, int vectorLength); 47 | 48 | /******************************************************************************* 49 | ** Inner functions which operate on state structs. 50 | *******************************************************************************/ 51 | double renyiMI(JointProbabilityState state, double alpha); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/WeightedEntropy.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** WeightedEntropy.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the entropy of a single variable H(X), 6 | ** the joint entropy of two variables H(X,Y), and the conditional entropy 7 | ** H(X|Y), while using a weight vector to modify the calculation. 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created: 20/6/2011 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #ifndef __WeightedEntropy_H 19 | #define __WeightedEntropy_H 20 | 21 | #include "MIToolbox/MIToolbox.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /******************************************************************************* 29 | ** calculateWeightedEntropy returns the entropy in log base LOG_BASE of dataVector 30 | ** H_w(X), weighted by weightVector 31 | ** 32 | ** length(vectors) == vectorLength otherwise it will segmentation fault 33 | *******************************************************************************/ 34 | double calcWeightedEntropy(uint *dataVector, double *weightVector, int vectorLength); 35 | double discAndCalcWeightedEntropy(double *dataVector, double *weightVector, int vectorLength); 36 | 37 | /******************************************************************************* 38 | ** calculateWeightedJointEntropy returns the entropy in log base LOG_BASE of the joint 39 | ** variable of firstVector and secondVector, H_w(XY), weighted by weightVector 40 | ** 41 | ** length(vectors) == vectorLength otherwise it will segmentation fault 42 | *******************************************************************************/ 43 | double calcWeightedJointEntropy(uint *firstVector, uint *secondVector, double *weightVector, int vectorLength); 44 | double discAndCalcWeightedJointEntropy(double *firstVector, double *secondVector, double *weightVector, int vectorLength); 45 | 46 | /******************************************************************************* 47 | ** calculateWeightedConditionalEntropy returns the entropy in log base LOG_BASE of 48 | ** dataVector conditioned on conditionVector, H_w(X|Y), weighted by weightVector 49 | ** 50 | ** length(vectors) == vectorLength otherwise it will segmentation fault 51 | *******************************************************************************/ 52 | double calcWeightedConditionalEntropy(uint *dataVector, uint *conditionVector, double *weightVector, int vectorLength); 53 | double discAndCalcWeightedConditionalEntropy(double *dataVector, double *conditionVector, double *weightVector, int vectorLength); 54 | 55 | /******************************************************************************* 56 | ** Inner functions which operate on state structs. 57 | *******************************************************************************/ 58 | double wEntropy(WeightedProbState state); 59 | double wJointEntropy(WeightedJointProbState state); 60 | double wCondEntropy(WeightedJointProbState state); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif 67 | 68 | -------------------------------------------------------------------------------- /MIToolbox-master/include/MIToolbox/WeightedMutualInformation.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** WeightedMutualInformation.h 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the mutual information of 6 | ** two variables X and Y, I(X;Y), to calculate the joint mutual information 7 | ** of two variables X & Z on the variable Y, I(XZ;Y), and the conditional 8 | ** mutual information I(x;Y|Z), while using a weight vector to modify 9 | ** the calculation. 10 | ** 11 | ** Author: Adam Pocock 12 | ** Created: 20/6/2011 13 | ** 14 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 15 | ** www.cs.manchester.ac.uk 16 | ** 17 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 18 | *******************************************************************************/ 19 | 20 | #ifndef __WeightedMutualInformation_H 21 | #define __WeightedMutualInformation_H 22 | 23 | #include "MIToolbox/MIToolbox.h" 24 | #include "MIToolbox/CalculateProbability.h" 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /******************************************************************************* 31 | ** calculateWeightedMutualInformation returns the LOG_BASE mutual information 32 | ** between dataVector and targetVector, I_w(X;Y), weighted by weightVector 33 | ** 34 | ** length(vectors) == vectorLength otherwise it will segmentation fault 35 | *******************************************************************************/ 36 | double calcWeightedMutualInformation(uint *dataVector, uint *targetVector, double *weightVector, int vectorLength); 37 | double discAndCalcWeightedMutualInformation(double *dataVector, double *targetVector, double *weightVector, int vectorLength); 38 | 39 | /******************************************************************************* 40 | ** calculateWeightedConditionalMutualInformation returns the LOG_BASE 41 | ** mutual information between dataVector and targetVector, conditioned on 42 | ** conditionVector, I(X;Y|Z), weighted by weightVector 43 | ** 44 | ** length(vectors) == vectorLength otherwise it will segmentation fault 45 | *******************************************************************************/ 46 | double calcWeightedConditionalMutualInformation(uint *dataVector, uint *targetVector, uint *conditionVector, double *weightVector, int vectorLength); 47 | double discAndCalcWeightedConditionalMutualInformation(double *dataVector, double *targetVector, double *conditionVector, double *weightVector, int vectorLength); 48 | 49 | /******************************************************************************* 50 | ** Inner functions which operate on state structs. 51 | *******************************************************************************/ 52 | double wmi(WeightedJointProbState state); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/CompileMIToolbox.m: -------------------------------------------------------------------------------- 1 | % Compiles the MIToolbox functions 2 | 3 | mex -I../include MIToolboxMex.c ../src/MutualInformation.c ../src/Entropy.c ../src/CalculateProbability.c ../src/ArrayOperations.c 4 | mex -I../include RenyiMIToolboxMex.c ../src/RenyiMutualInformation.c ../src/RenyiEntropy.c ../src/CalculateProbability.c ../src/ArrayOperations.c 5 | mex -I../include WeightedMIToolboxMex.c ../src/WeightedMutualInformation.c ../src/WeightedEntropy.c ../src/CalculateProbability.c ../src/ArrayOperations.c 6 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/MIToolbox.m: -------------------------------------------------------------------------------- 1 | function [varargout] = MIToolbox(functionName, varargin) 2 | %function [varargout] = MIToolbox(functionName, varargin) 3 | % 4 | %Provides access to the functions in MIToolboxMex 5 | % 6 | %Expects column vectors, will not work with row vectors 7 | % 8 | %Function list 9 | %"joint" = joint variable of the matrix 10 | %"entropy" or "h" = H(X) 11 | %"ConditionalEntropy" or "condh" = H(X|Y) 12 | %"mi" = I(X;Y) 13 | %"ConditionalMI" or "cmi" = I(X;Y|Z) 14 | % 15 | %Arguments and returned values 16 | %[jointVariable] = joint(matrix) 17 | %[entropy] = H(X) = H(vector) 18 | %[entropy] = H(X|Y) = H(vector,condition) 19 | %[mi] = I(X;Y) = I(vector,target) 20 | %[mi] = I(X;Y|Z) = I(vector,target,condition) 21 | % 22 | %Internal MIToolbox function number 23 | %Joint = 3 24 | %Entropy = 4 25 | %Conditional Entropy = 6 26 | %Mutual Information = 7 27 | %Conditional MI = 8 28 | 29 | for i = 1:length(varargin) 30 | if (~isa(varargin{i},'double')) 31 | error('Error, MIToolbox requires inputs to be double vector or matrices') 32 | end 33 | end 34 | 35 | if (strcmpi(functionName,'Joint') || strcmpi(functionName,'Merge')) 36 | [varargout{1}] = MIToolboxMex(3,varargin{1}); 37 | elseif (strcmpi(functionName,'Entropy') || strcmpi(functionName,'h')) 38 | %disp('Calculating Entropy'); 39 | if (size(varargin{1},2)>1) 40 | mergedVector = MIToolboxMex(3,varargin{1}); 41 | else 42 | mergedVector = varargin{1}; 43 | end 44 | [varargout{1}] = MIToolboxMex(4,mergedVector); 45 | elseif ((strcmpi(functionName,'ConditionalEntropy')) || strcmpi(functionName,'condh')) 46 | if (size(varargin{1},2)>1) 47 | mergedFirst = MIToolboxMex(3,varargin{1}); 48 | else 49 | mergedFirst = varargin{1}; 50 | end 51 | if (size(varargin{2},2)>1) 52 | mergedSecond = MIToolboxMex(3,varargin{2}); 53 | else 54 | mergedSecond = varargin{2}; 55 | end 56 | [varargout{1}] = MIToolboxMex(6,mergedFirst,mergedSecond); 57 | elseif (strcmpi(functionName,'mi')) 58 | if (size(varargin{1},2)>1) 59 | mergedFirst = MIToolboxMex(3,varargin{1}); 60 | else 61 | mergedFirst = varargin{1}; 62 | end 63 | if (size(varargin{2},2)>1) 64 | mergedSecond = MIToolboxMex(3,varargin{2}); 65 | else 66 | mergedSecond = varargin{2}; 67 | end 68 | [varargout{1}] = MIToolboxMex(7,mergedFirst,mergedSecond); 69 | elseif (strcmpi(functionName,'ConditionalMI') || strcmpi(functionName,'cmi')) 70 | if (size(varargin{1},2)>1) 71 | mergedFirst = MIToolboxMex(3,varargin{1}); 72 | else 73 | mergedFirst = varargin{1}; 74 | end 75 | if (size(varargin{2},2)>1) 76 | mergedSecond = MIToolboxMex(3,varargin{2}); 77 | else 78 | mergedSecond = varargin{2}; 79 | end 80 | if (size(varargin{3},2)>1) 81 | mergedThird = MIToolboxMex(3,varargin{3}); 82 | else 83 | mergedThird = varargin{3}; 84 | end 85 | [varargout{1}] = MIToolboxMex(8,mergedFirst,mergedSecond,mergedThird); 86 | else 87 | varargout{1} = 0; 88 | disp(['Unrecognised functionName ' functionName]); 89 | end 90 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/RenyiMIToolbox.m: -------------------------------------------------------------------------------- 1 | function [varargout] = RenyiMIToolbox(functionName, alpha, varargin) 2 | %function [varargout] = RenyiMIToolbox(functionName, alpha, varargin) 3 | % 4 | %Provides access to the functions in RenyiMIToolboxMex 5 | % 6 | %Expects column vectors, will not work with row vectors 7 | % 8 | %Function list 9 | %"Entropy" = H_{\alpha}(X) = 1 10 | %"MI" = I_{\alpha}(X;Y) = 3 11 | % 12 | %Arguments and returned values 13 | %[entropy] = H_\alpha(X) = H(alpha,vector) 14 | %[mi] = I_\alpha(X;Y) = I(alpha,vector,target) 15 | % 16 | %Internal RenyiMIToolbox function number 17 | %Renyi Entropy = 1; 18 | %Renyi MI = 3; 19 | 20 | for i = 1:length(varargin) 21 | if (~isa(varargin{i},'double')) 22 | error('Error, MIToolbox requires inputs to be double vector or matrices') 23 | end 24 | end 25 | 26 | if (alpha ~= 1) 27 | if (strcmpi(functionName,'Entropy') || strcmpi(functionName,'h')) 28 | %disp('Calculating Entropy'); 29 | if (size(varargin{1},2)>1) 30 | mergedVector = MIToolboxMex(3,varargin{1}); 31 | else 32 | mergedVector = varargin{1}; 33 | end 34 | [varargout{1}] = RenyiMIToolboxMex(1,alpha,mergedVector); 35 | elseif (strcmpi(functionName,'MI')) 36 | if (size(varargin{1},2)>1) 37 | mergedFirst = MIToolboxMex(3,varargin{1}); 38 | else 39 | mergedFirst = varargin{1}; 40 | end 41 | if (size(varargin{2},2)>1) 42 | mergedSecond = MIToolboxMex(3,varargin{2}); 43 | else 44 | mergedSecond = varargin{2}; 45 | end 46 | [varargout{1}] = RenyiMIToolboxMex(3,alpha,mergedFirst,mergedSecond); 47 | else 48 | varargout{1} = 0; 49 | disp(['Unrecognised functionName ' functionName]); 50 | end 51 | else 52 | disp('For alpha = 1 use functions in MIToolbox.m'); 53 | disp('as those functions are the implementation of Shannon''s Information Theory'); 54 | end 55 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/RenyiMIToolboxMex.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** RenyiMIToolboxMex.c 3 | ** is the MATLAB entry point for the Renyi Entropy and MI MIToolbox functions 4 | ** when called from a MATLAB/OCTAVE script. 5 | ** 6 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 7 | ** www.cs.manchester.ac.uk 8 | ** 9 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 10 | *******************************************************************************/ 11 | 12 | #include "MIToolbox/MIToolbox.h" 13 | #include "MIToolbox/ArrayOperations.h" 14 | #include "MIToolbox/RenyiEntropy.h" 15 | #include "MIToolbox/RenyiMutualInformation.h" 16 | 17 | /******************************************************************************* 18 | **entry point for the mex call 19 | **nlhs - number of outputs 20 | **plhs - pointer to array of outputs 21 | **nrhs - number of inputs 22 | **prhs - pointer to array of inputs 23 | *******************************************************************************/ 24 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 25 | { 26 | /***************************************************************************** 27 | ** this function takes a flag and 2 or 3 other arguments 28 | ** the first is a scalar alpha value, and the remainder are 29 | ** arrays. It returns a Renyi entropy or mutual information using the 30 | ** alpha divergence. 31 | *****************************************************************************/ 32 | 33 | int flag, numberOfSamples, checkSamples, numberOfFeatures, checkFeatures; 34 | double alpha; 35 | double *dataVector, *firstVector, *secondVector, *output; 36 | 37 | /*if (nlhs != 1) 38 | { 39 | printf("Incorrect number of output arguments\n"); 40 | }//if not 1 output 41 | */ 42 | switch (nrhs) 43 | { 44 | case 3: 45 | { 46 | /*printf("Must be H_\alpha(X)\n");*/ 47 | break; 48 | } 49 | case 4: 50 | { 51 | /*printf("Must be H_\alpha(XY), I_\alpha(X;Y)\n");*/ 52 | break; 53 | } 54 | default: 55 | { 56 | printf("Incorrect number of arguments, format is RenyiMIToolbox(\"FLAG\",varargin)\n"); 57 | break; 58 | } 59 | } 60 | 61 | /* number to function map 62 | ** 1 = H(X) 63 | ** 2 = H(XY) 64 | ** 3 = I(X;Y) 65 | */ 66 | 67 | flag = *mxGetPr(prhs[0]); 68 | 69 | switch (flag) 70 | { 71 | case 1: 72 | { 73 | /* 74 | **H_{\alpha}(X) 75 | */ 76 | alpha = mxGetScalar(prhs[1]); 77 | numberOfSamples = mxGetM(prhs[2]); 78 | numberOfFeatures = mxGetN(prhs[2]); 79 | dataVector = (double *) mxGetPr(prhs[2]); 80 | 81 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 82 | output = (double *) mxGetPr(plhs[0]); 83 | 84 | if (numberOfFeatures == 1) 85 | { 86 | /*double discAndCalcRenyiEntropy(double alpha, double *dataVector, long vectorLength);*/ 87 | *output = discAndCalcRenyiEntropy(alpha,dataVector,numberOfSamples); 88 | } 89 | else 90 | { 91 | printf("No columns in input\n"); 92 | *output = -1.0; 93 | } 94 | break; 95 | }/*case 1 - H_{\alpha}(X)*/ 96 | case 2: 97 | { 98 | /* 99 | **H_{\alpha}(XY) 100 | */ 101 | alpha = mxGetScalar(prhs[1]); 102 | 103 | numberOfSamples = mxGetM(prhs[2]); 104 | checkSamples = mxGetM(prhs[3]); 105 | 106 | numberOfFeatures = mxGetN(prhs[2]); 107 | checkFeatures = mxGetN(prhs[3]); 108 | 109 | firstVector = mxGetPr(prhs[2]); 110 | secondVector = mxGetPr(prhs[3]); 111 | 112 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 113 | output = (double *)mxGetPr(plhs[0]); 114 | 115 | if ((numberOfFeatures == 1) && (checkFeatures == 1)) 116 | { 117 | if ((numberOfSamples == 0) || (checkSamples == 0)) 118 | { 119 | *output = 0.0; 120 | } 121 | else if (numberOfSamples == checkSamples) 122 | { 123 | /*double discAndCalcJointRenyiEntropy(double alpha, double *firstVector, double *secondVector, long vectorLength);*/ 124 | *output = discAndCalcJointRenyiEntropy(alpha,firstVector,secondVector,numberOfSamples); 125 | } 126 | else 127 | { 128 | printf("Vector lengths do not match, they must be the same length"); 129 | *output = -1.0; 130 | } 131 | } 132 | else 133 | { 134 | printf("No columns in input\n"); 135 | *output = -1.0; 136 | } 137 | break; 138 | }/*case 2 - H_{\alpha}(XY)*/ 139 | case 3: 140 | { 141 | /* 142 | **I_{\alpha}(X;Y) 143 | */ 144 | alpha = mxGetScalar(prhs[1]); 145 | 146 | numberOfSamples = mxGetM(prhs[2]); 147 | checkSamples = mxGetM(prhs[3]); 148 | 149 | numberOfFeatures = mxGetN(prhs[2]); 150 | checkFeatures = mxGetN(prhs[3]); 151 | 152 | firstVector = mxGetPr(prhs[2]); 153 | secondVector = mxGetPr(prhs[3]); 154 | 155 | plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); 156 | output = (double *)mxGetPr(plhs[0]); 157 | 158 | if ((numberOfFeatures == 1) && (checkFeatures == 1)) 159 | { 160 | if ((numberOfSamples == 0) || (checkSamples == 0)) 161 | { 162 | *output = 0.0; 163 | } 164 | else if (numberOfSamples == checkSamples) 165 | { 166 | /*double discAndCalcRenyiMIDivergence(double alpha, double *dataVector, double *targetVector, long vectorLength);*/ 167 | *output = discAndCalcRenyiMIDivergence(alpha,firstVector,secondVector,numberOfSamples); 168 | } 169 | else 170 | { 171 | printf("Vector lengths do not match, they must be the same length"); 172 | *output = -1.0; 173 | } 174 | } 175 | else 176 | { 177 | printf("No columns in input\n"); 178 | *output = -1.0; 179 | } 180 | break; 181 | }/*case 3 - I_{\alpha}(X;Y)*/ 182 | default: 183 | { 184 | printf("Unrecognised flag\n"); 185 | break; 186 | }/*default*/ 187 | }/*switch(flag)*/ 188 | 189 | return; 190 | }/*mexFunction()*/ 191 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/WeightedMIToolbox.m: -------------------------------------------------------------------------------- 1 | function [varargout] = WeightedMIToolbox(functionName, weightVector, varargin) 2 | %function [varargout] = WeightedMIToolbox(functionName, weightVector, varargin) 3 | % 4 | %Provides access to the functions in WeightedMIToolboxMex 5 | % 6 | %Expects column vectors, will not work with row vectors 7 | % 8 | %Function list 9 | %"entropy" or "h" = H(X) 10 | %"ConditionalEntropy" or "condh" = H(X|Y) 11 | %"mi" = I(X;Y) 12 | %"ConditionalMI" or "cmi" = I(X;Y|Z) 13 | % 14 | %Arguments and returned values 15 | %[entropy] = H_w(X) = H_w(vector) 16 | %[entropy] = H_w(X|Y) = H_w(vector,condition) 17 | %[mi] = I_w(X;Y) = I_w(vector,target) 18 | %[mi] = I_w(X;Y|Z) = I_w(vector,target,condition) 19 | % 20 | %Internal MIToolbox function number 21 | %Entropy = 1 22 | %Conditional Entropy = 3 23 | %Mutual Information = 4 24 | %Conditional MI = 5 25 | 26 | for i = 1:length(varargin) 27 | if (~isa(varargin{i},'double')) 28 | error('Error, MIToolbox requires inputs to be double vector or matrices') 29 | end 30 | end 31 | 32 | if (strcmpi(functionName,'Entropy') || strcmpi(functionName,'h')) 33 | %disp('Calculating Entropy'); 34 | if (size(varargin{1},2)>1) 35 | mergedVector = MIToolboxMex(3,varargin{1}); 36 | else 37 | mergedVector = varargin{1}; 38 | end 39 | [varargout{1}] = WeightedMIToolboxMex(1,weightVector,mergedVector); 40 | elseif ((strcmpi(functionName,'JointEntropy')) || strcmpi(functionName,'jointh')) 41 | if (size(varargin{1},2)>1) 42 | mergedFirst = MIToolboxMex(3,varargin{1}); 43 | else 44 | mergedFirst = varargin{1}; 45 | end 46 | if (size(varargin{2},2)>1) 47 | mergedSecond = MIToolboxMex(3,varargin{2}); 48 | else 49 | mergedSecond = varargin{2}; 50 | end 51 | [varargout{1}] = WeightedMIToolboxMex(2,weightVector,mergedFirst,mergedSecond); 52 | elseif ((strcmpi(functionName,'ConditionalEntropy')) || strcmpi(functionName,'condh')) 53 | if (size(varargin{1},2)>1) 54 | mergedFirst = MIToolboxMex(3,varargin{1}); 55 | else 56 | mergedFirst = varargin{1}; 57 | end 58 | if (size(varargin{2},2)>1) 59 | mergedSecond = MIToolboxMex(3,varargin{2}); 60 | else 61 | mergedSecond = varargin{2}; 62 | end 63 | [varargout{1}] = WeightedMIToolboxMex(3,weightVector,mergedFirst,mergedSecond); 64 | elseif (strcmpi(functionName,'mi')) 65 | if (size(varargin{1},2)>1) 66 | mergedFirst = MIToolboxMex(3,varargin{1}); 67 | else 68 | mergedFirst = varargin{1}; 69 | end 70 | if (size(varargin{2},2)>1) 71 | mergedSecond = MIToolboxMex(3,varargin{2}); 72 | else 73 | mergedSecond = varargin{2}; 74 | end 75 | [varargout{1}] = WeightedMIToolboxMex(4,weightVector,mergedFirst,mergedSecond); 76 | elseif (strcmpi(functionName,'ConditionalMI') || strcmpi(functionName,'cmi')) 77 | if (size(varargin{1},2)>1) 78 | mergedFirst = MIToolboxMex(3,varargin{1}); 79 | else 80 | mergedFirst = varargin{1}; 81 | end 82 | if (size(varargin{2},2)>1) 83 | mergedSecond = MIToolboxMex(3,varargin{2}); 84 | else 85 | mergedSecond = varargin{2}; 86 | end 87 | if (size(varargin{3},2)>1) 88 | mergedThird = MIToolboxMex(3,varargin{3}); 89 | else 90 | mergedThird = varargin{3}; 91 | end 92 | [varargout{1}] = WeightedMIToolboxMex(5,weightVector,mergedFirst,mergedSecond,mergedThird); 93 | else 94 | varargout{1} = 0; 95 | disp(['Unrecognised functionName ' functionName]); 96 | end 97 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/cmi.m: -------------------------------------------------------------------------------- 1 | function output = cmi(X,Y,Z) 2 | %function output = cmi(X,Y,Z) 3 | %X, Y & Z can be matrices which are converted into a joint variable 4 | %before computation 5 | % 6 | %expects variables to be column-wise 7 | % 8 | %returns the mutual information between X and Y conditioned on Z, I(X;Y|Z) 9 | 10 | if nargin == 3 11 | if (~isa(X,'double') || ~isa(Y,'double') || ~isa(Z,'double')) 12 | error('Error, inputs must be double vectors or matrices') 13 | end 14 | if (size(X,2)>1) 15 | mergedFirst = MIToolboxMex(3,X); 16 | else 17 | mergedFirst = X; 18 | end 19 | if (size(Y,2)>1) 20 | mergedSecond = MIToolboxMex(3,Y); 21 | else 22 | mergedSecond = Y; 23 | end 24 | if (size(Z,2)>1) 25 | mergedThird = MIToolboxMex(3,Z); 26 | else 27 | mergedThird = Z; 28 | end 29 | [output] = MIToolboxMex(8,mergedFirst,mergedSecond,mergedThird); 30 | elseif nargin == 2 31 | if (~isa(X,'double') || ~isa(Y,'double')) 32 | error('Error, inputs must be double vectors or matrices') 33 | end 34 | output = mi(X,Y); 35 | else 36 | output = 0; 37 | end 38 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/condh.m: -------------------------------------------------------------------------------- 1 | function output = condh(X,Y) 2 | %function output = condh(X,Y) 3 | %X & Y can be matrices which are converted into a joint variable 4 | %before computation 5 | % 6 | %expects variables to be column-wise 7 | % 8 | %returns the conditional entropy of X given Y, H(X|Y) 9 | 10 | if nargin == 2 11 | if (~isa(X,'double') || ~isa(Y,'double')) 12 | error('Error, inputs must be double vectors or matrices') 13 | end 14 | if (size(X,2)>1) 15 | mergedFirst = MIToolboxMex(3,X); 16 | else 17 | mergedFirst = X; 18 | end 19 | if (size(Y,2)>1) 20 | mergedSecond = MIToolboxMex(3,Y); 21 | else 22 | mergedSecond = Y; 23 | end 24 | [output] = MIToolboxMex(6,mergedFirst,mergedSecond); 25 | elseif nargin == 1 26 | if (~isa(X,'double')) 27 | error('Error, inputs must be double vectors or matrices') 28 | end 29 | output = h(X); 30 | else 31 | output = 0; 32 | end 33 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/CMIM.m: -------------------------------------------------------------------------------- 1 | function selectedFeatures = CMIM(k, featureMatrix, classColumn) 2 | %function selectedFeatures = CMIM(k, featureMatrix, classColumn) 3 | %Computes conditional mutual information maximisation algorithm from 4 | %"Fast Binary Feature Selection with Conditional Mutual Information" 5 | %by F. Fleuret (2004) 6 | 7 | %Computes the top k features from 8 | %a dataset featureMatrix with n training examples and m features 9 | %with the classes held in classColumn. 10 | 11 | noOfTraining = size(classColumn,1); 12 | noOfFeatures = size(featureMatrix,2); 13 | 14 | partialScore = zeros(noOfFeatures,1); 15 | m = zeros(noOfFeatures,1); 16 | score = 0; 17 | answerFeatures = zeros(k,1); 18 | highestMI = 0; 19 | highestMICounter = 0; 20 | 21 | for n = 1 : noOfFeatures 22 | partialScore(n) = mi(featureMatrix(:,n),classColumn); 23 | if partialScore(n) > highestMI 24 | highestMI = partialScore(n); 25 | highestMICounter = n; 26 | end 27 | end 28 | 29 | answerFeatures(1) = highestMICounter; 30 | 31 | for i = 2 : k 32 | score = 0; 33 | limitI = i - 1; 34 | for n = 1 : noOfFeatures 35 | while ((partialScore(n) >= score) && (m(n) < limitI)) 36 | m(n) = m(n) + 1; 37 | conditionalInfo = cmi(featureMatrix(:,n),classColumn,featureMatrix(:,answerFeatures(m(n)))); 38 | if partialScore(n) > conditionalInfo 39 | partialScore(n) = conditionalInfo; 40 | end 41 | end 42 | if partialScore(n) >= score 43 | score = partialScore(n); 44 | answerFeatures(i) = n; 45 | end 46 | end 47 | end 48 | 49 | selectedFeatures = answerFeatures; 50 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/CMIM_Mex.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** Demonstration feature selection algorithm - MATLAB r2009a 3 | ** 4 | ** Initial Version - 13/06/2008 5 | ** Updated - 07/07/2010 6 | ** based on CMIM.m 7 | ** 8 | ** Conditional Mutual Information Maximisation 9 | ** in 10 | ** "Fast Binary Feature Selection using Conditional Mutual Information Maximisation 11 | ** F. Fleuret (2004) 12 | ** 13 | ** Author - Adam Pocock 14 | ** Demonstration code for MIToolbox 15 | *******************************************************************************/ 16 | 17 | #include "mex.h" 18 | #include "MIToolbox/MIToolbox.h" 19 | #include "MIToolbox/MutualInformation.h" 20 | 21 | void CMIMCalculation(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures) 22 | { 23 | /*holds the class MI values 24 | **the class MI doubles as the partial score from the CMIM paper 25 | */ 26 | double *classMI = (double *)mxCalloc(noOfFeatures,sizeof(double)); 27 | /*in the CMIM paper, m = lastUsedFeature*/ 28 | int *lastUsedFeature = (int *)mxCalloc(noOfFeatures,sizeof(int)); 29 | 30 | double score, conditionalInfo; 31 | int iMinus, currentFeature; 32 | 33 | double maxMI = 0.0; 34 | int maxMICounter = -1; 35 | 36 | int j,i; 37 | 38 | double **feature2D = (double**) mxCalloc(noOfFeatures,sizeof(double*)); 39 | 40 | for(j = 0; j < noOfFeatures; j++) 41 | { 42 | feature2D[j] = featureMatrix + (int)j*noOfSamples; 43 | } 44 | 45 | for (i = 0; i < noOfFeatures;i++) 46 | { 47 | classMI[i] = discAndCalcMutualInformation(feature2D[i], classColumn, noOfSamples); 48 | 49 | if (classMI[i] > maxMI) 50 | { 51 | maxMI = classMI[i]; 52 | maxMICounter = i; 53 | }/*if bigger than current maximum*/ 54 | }/*for noOfFeatures - filling classMI*/ 55 | 56 | outputFeatures[0] = maxMICounter; 57 | 58 | /***************************************************************************** 59 | ** We have populated the classMI array, and selected the highest 60 | ** MI feature as the first output feature 61 | ** Now we move into the CMIM algorithm 62 | *****************************************************************************/ 63 | 64 | for (i = 1; i < k; i++) 65 | { 66 | score = 0.0; 67 | iMinus = i-1; 68 | 69 | for (j = 0; j < noOfFeatures; j++) 70 | { 71 | while ((classMI[j] > score) && (lastUsedFeature[j] < i)) 72 | { 73 | /*double discAndCalcConditionalMutualInformation(double *firstVector, double *targetVector, double *conditionVector, int vectorLength);*/ 74 | currentFeature = (int) outputFeatures[lastUsedFeature[j]]; 75 | conditionalInfo = discAndCalcConditionalMutualInformation(feature2D[j],classColumn,feature2D[currentFeature],noOfSamples); 76 | if (classMI[j] > conditionalInfo) 77 | { 78 | classMI[j] = conditionalInfo; 79 | }/*reset classMI*/ 80 | /*moved due to C indexing from 0 rather than 1*/ 81 | lastUsedFeature[j] += 1; 82 | }/*while partial score greater than score & not reached last feature*/ 83 | if (classMI[j] > score) 84 | { 85 | score = classMI[j]; 86 | outputFeatures[i] = j; 87 | }/*if partial score still greater than score*/ 88 | }/*for number of features*/ 89 | }/*for the number of features to select*/ 90 | 91 | 92 | for (i = 0; i < k; i++) 93 | { 94 | outputFeatures[i] += 1; /*C indexes from 0 not 1*/ 95 | }/*for number of selected features*/ 96 | 97 | }/*CMIMCalculation*/ 98 | 99 | /*entry point for the mex call 100 | **nlhs - number of outputs 101 | **plhs - pointer to array of outputs 102 | **nrhs - number of inputs 103 | **prhs - pointer to array of inputs 104 | */ 105 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 106 | { 107 | /************************************************************* 108 | ** this function takes 3 arguments: 109 | ** k = number of features to select, 110 | ** featureMatrix[][] = matrix of features 111 | ** classColumn[] = targets 112 | ** the arguments should all be discrete integers. 113 | ** and has one output: 114 | ** selectedFeatures[] of size k 115 | *************************************************************/ 116 | 117 | int k, numberOfFeatures, numberOfSamples, numberOfTargets; 118 | double *featureMatrix, *targets, *output; 119 | 120 | 121 | if (nlhs != 1) 122 | { 123 | printf("Incorrect number of output arguments"); 124 | }/*if not 1 output*/ 125 | if (nrhs != 3) 126 | { 127 | printf("Incorrect number of input arguments"); 128 | }/*if not 3 inputs*/ 129 | 130 | /*get the number of features to select, cast out as it is a double*/ 131 | k = (int) mxGetScalar(prhs[0]); 132 | 133 | numberOfFeatures = mxGetN(prhs[1]); 134 | numberOfSamples = mxGetM(prhs[1]); 135 | 136 | numberOfTargets = mxGetM(prhs[2]); 137 | 138 | if (numberOfTargets != numberOfSamples) 139 | { 140 | printf("Number of targets must match number of samples\n"); 141 | printf("Number of targets = %d, Number of Samples = %d, Number of Features = %d\n",numberOfTargets,numberOfSamples,numberOfFeatures); 142 | 143 | plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); 144 | }/*if size mismatch*/ 145 | else 146 | { 147 | 148 | featureMatrix = mxGetPr(prhs[1]); 149 | targets = mxGetPr(prhs[2]); 150 | 151 | plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); 152 | output = (double *)mxGetPr(plhs[0]); 153 | 154 | /*void CMIMCalculation(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ 155 | CMIMCalculation(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); 156 | } 157 | 158 | return; 159 | }/*mexFunction()*/ 160 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/CompileDemos.m: -------------------------------------------------------------------------------- 1 | mex -I../../ mRMR_D_Mex.c ../../src/MutualInformation.c ../../src/ArrayOperations.c ../../src/CalculateProbability.c ../../src/Entropy.c 2 | mex -I../../ DISR_Mex.c ../../src/MutualInformation.c ../../src/ArrayOperations.c ../../src/CalculateProbability.c ../../src/Entropy.c 3 | mex -I../../ CMIM_Mex.c ../../src/MutualInformation.c ../../src/ArrayOperations.c ../../src/CalculateProbability.c ../../src/Entropy.c 4 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/DISR.m: -------------------------------------------------------------------------------- 1 | function selectedFeatures = DISR(k, featureMatrix, classColumn) 2 | %function selectedFeatures = DISR(k, featureMatrix, classColumn) 3 | % 4 | %Computers optimal features according to DISR algorithm from 5 | %On the Use of variable "complementarity for feature selection" 6 | %by P Meyer, G Bontempi (2006) 7 | % 8 | %Computes the top k features from 9 | %a dataset featureMatrix with n training examples and m features 10 | %with the classes held in classColumn. 11 | % 12 | %DISR - arg(Xi) max(sum(Xj mem XS)(SimRel(Xij,Y))) 13 | %where SimRel = MI(Xij,Y) / H(Xij,Y) 14 | 15 | totalFeatures = size(featureMatrix,2); 16 | classMI = zeros(totalFeatures,1); 17 | unselectedFeatures = ones(totalFeatures,1); 18 | score = 0; 19 | currentScore = 0; 20 | innerScore = 0; 21 | iMinus = 0; 22 | answerFeatures = zeros(k,1); 23 | highestMI = 0; 24 | highestMICounter = 0; 25 | currentHighestFeature = 0; 26 | 27 | %create a matrix to hold the SRs of a feature pair. 28 | %initialised to -1 as you can't get a negative SR. 29 | featureSRMatrix = -(ones(k,totalFeatures)); 30 | 31 | for n = 1 : totalFeatures 32 | classMI(n) = mi(featureMatrix(:,n),classColumn); 33 | if classMI(n) > highestMI 34 | highestMI = classMI(n); 35 | highestMICounter = n; 36 | end 37 | end 38 | 39 | answerFeatures(1) = highestMICounter; 40 | unselectedFeatures(highestMICounter) = 0; 41 | 42 | for i = 2 : k 43 | score = 0; 44 | currentHighestFeature = 0; 45 | iMinus = i-1; 46 | for j = 1 : totalFeatures 47 | if unselectedFeatures(j) == 1 48 | %DISR - arg(Xi) max(sum(Xj mem XS)(SimRel(Xij,Y))) 49 | %where SimRel = MI(Xij,Y) / H(Xij,Y) 50 | currentScore = 0; 51 | for m = 1 : iMinus 52 | if featureSRMatrix(m,j) == -1 53 | unionedFeatures = joint([featureMatrix(:,answerFeatures(m)),featureMatrix(:,j)]); 54 | tempUnionMI = mi(unionedFeatures,classColumn); 55 | tempTripEntropy = h([unionedFeatures,classColumn]); 56 | featureSRMatrix(m,j) = tempUnionMI/tempTripEntropy; 57 | end 58 | 59 | currentScore = currentScore + featureSRMatrix(m,j); 60 | end 61 | if (currentScore > score) 62 | score = currentScore; 63 | currentHighestFeature = j; 64 | end 65 | end 66 | end 67 | %now highest feature is selected in currentHighestFeature 68 | %store it 69 | unselectedFeatures(currentHighestFeature) = 0; 70 | answerFeatures(i) = currentHighestFeature; 71 | end 72 | 73 | selectedFeatures = answerFeatures; 74 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/IAMB.m: -------------------------------------------------------------------------------- 1 | function [cmb association] = IAMB( data, targetindex, THRESHOLD) 2 | %function [cmb association] = IAMB( data, targetindex, THRESHOLD) 3 | % 4 | %Performs the IAMB algorithm of Tsmardinos et al. (2003) 5 | %from "Towards principled feature selection: Relevancy, filters and wrappers" 6 | 7 | if (nargin == 2) 8 | THRESHOLD = 0.02; 9 | end 10 | 11 | numf = size(data,2); 12 | targets = data(:,targetindex); 13 | data(:,targetindex) = -10; 14 | 15 | cmb = []; 16 | 17 | finished = false; 18 | while ~finished 19 | for n = 1:numf 20 | cmbVector = joint(data(:,cmb)); 21 | if isempty(cmb) 22 | association(n) = mi( data(:,n), targets ); 23 | end 24 | 25 | if ismember(n,cmb) 26 | association(n) = -10; %arbtirary large negative constant 27 | else 28 | association(n) = cmi( data(:,n), targets, cmbVector); 29 | end 30 | end 31 | 32 | [maxval maxidx] = max(association); 33 | if maxval < THRESHOLD 34 | finished = true; 35 | else 36 | cmb = [ cmb maxidx ]; 37 | end 38 | end 39 | 40 | finished = false; 41 | while ~finished && ~isempty(cmb) 42 | association = []; 43 | for n = 1:length(cmb) 44 | cmbwithoutn = cmb; 45 | cmbwithoutn(n)=[]; 46 | association(n) = cmi( data(:,cmb(n)), targets, data(:,cmbwithoutn) ); 47 | end 48 | 49 | [minval minidx] = min(association); 50 | if minval > THRESHOLD 51 | finished = true; 52 | else 53 | cmb(minidx) = []; 54 | end 55 | end 56 | 57 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/mRMR_D.m: -------------------------------------------------------------------------------- 1 | function selectedFeatures = mRMR_D(k, featureMatrix, classColumn) 2 | %function selectedFeatures = mRMR_D(k, featureMatrix, classColumn) 3 | % 4 | %Selects optimal features according to the mRMR-D algorithm from 5 | %"Feature Selection Based on Mutual Information: Criteria of Max-Dependency, Max-Relevance, and Min-Redundancy" 6 | %by H. Peng et al. (2005) 7 | % 8 | %Calculates the top k features 9 | %a dataset featureMatrix with n training examples and m features 10 | %with the classes held in classColumn (an n x 1 vector) 11 | 12 | noOfTraining = size(classColumn,1); 13 | noOfFeatures = size(featureMatrix,2); 14 | unselectedFeatures = ones(noOfFeatures,1); 15 | 16 | classMI = zeros(noOfFeatures,1); 17 | answerFeatures = zeros(k,1); 18 | highestMI = 0; 19 | highestMICounter = 0; 20 | currentHighestFeature = 0; 21 | 22 | featureMIMatrix = -(ones(k,noOfFeatures)); 23 | 24 | %setup the mi against the class 25 | for n = 1 : noOfFeatures 26 | classMI(n) = mi(featureMatrix(:,n),classColumn); 27 | if classMI(n) > highestMI 28 | highestMI = classMI(n); 29 | highestMICounter = n; 30 | end 31 | end 32 | 33 | answerFeatures(1) = highestMICounter; 34 | unselectedFeatures(highestMICounter) = 0; 35 | 36 | %iterate over the number of features to select 37 | for i = 2:k 38 | score = -100; 39 | currentHighestFeature = 0; 40 | iMinus = i-1; 41 | for j = 1 : noOfFeatures 42 | if unselectedFeatures(j) == 1 43 | currentMIScore = 0; 44 | for m = 1 : iMinus 45 | if featureMIMatrix(m,j) == -1 46 | featureMIMatrix(m,j) = mi(featureMatrix(:,j),featureMatrix(:,answerFeatures(m))); 47 | end 48 | currentMIScore = currentMIScore + featureMIMatrix(m,j); 49 | end 50 | currentScore = classMI(j) - (currentMIScore/iMinus); 51 | 52 | if (currentScore > score) 53 | score = currentScore; 54 | currentHighestFeature = j; 55 | end 56 | end 57 | end 58 | 59 | if score < 0 60 | disp(['at selection ' int2str(j) ' mRMRD is negative with value ' num2str(score)]); 61 | end 62 | 63 | %now highest feature is selected in currentHighestFeature 64 | %store it 65 | unselectedFeatures(currentHighestFeature) = 0; 66 | answerFeatures(i) = currentHighestFeature; 67 | end 68 | 69 | selectedFeatures = answerFeatures; 70 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/demonstration_algorithms/mRMR_D_Mex.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** Demonstration feature selection algorithm - MATLAB r2009a 3 | ** 4 | ** Initial Version - 13/06/2008 5 | ** Updated - 07/07/2010 6 | ** based on mRMR_D.m 7 | ** 8 | ** Minimum Relevance Maximum Redundancy 9 | ** in 10 | ** "Feature Selection Based on Mutual Information: Criteria of Max-Dependency, Max-Relevance, and Min-Redundancy" 11 | ** H. Peng et al. (2005) 12 | ** 13 | ** Author - Adam Pocock 14 | ** Demonstration code for MIToolbox 15 | *******************************************************************************/ 16 | 17 | #include "mex.h" 18 | #include "MIToolbox/MIToolbox.h" 19 | #include "MIToolbox/MutualInformation.h" 20 | 21 | void mRMRCalculation(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures) 22 | { 23 | double **feature2D = (double**) mxCalloc(noOfFeatures,sizeof(double*)); 24 | /*holds the class MI values*/ 25 | double *classMI = (double *) mxCalloc(noOfFeatures,sizeof(double)); 26 | int *selectedFeatures = (int *) mxCalloc(noOfFeatures,sizeof(int)); 27 | /*holds the intra feature MI values*/ 28 | int sizeOfMatrix = k*noOfFeatures; 29 | double *featureMIMatrix = (double *)mxCalloc(sizeOfMatrix,sizeof(double)); 30 | 31 | double maxMI = 0.0; 32 | int maxMICounter = -1; 33 | 34 | /*init variables*/ 35 | 36 | double score, currentScore, totalFeatureMI; 37 | int currentHighestFeature; 38 | 39 | int arrayPosition, i, j, x; 40 | 41 | for(j = 0; j < noOfFeatures; j++) 42 | { 43 | feature2D[j] = featureMatrix + (int)j*noOfSamples; 44 | } 45 | 46 | for (i = 0; i < sizeOfMatrix;i++) 47 | { 48 | featureMIMatrix[i] = -1; 49 | }/*for featureMIMatrix - blank to -1*/ 50 | 51 | 52 | for (i = 0; i < noOfFeatures;i++) 53 | { 54 | classMI[i] = discAndCalcMutualInformation(feature2D[i], classColumn, noOfSamples); 55 | if (classMI[i] > maxMI) 56 | { 57 | maxMI = classMI[i]; 58 | maxMICounter = i; 59 | }/*if bigger than current maximum*/ 60 | }/*for noOfFeatures - filling classMI*/ 61 | 62 | selectedFeatures[maxMICounter] = 1; 63 | outputFeatures[0] = maxMICounter; 64 | 65 | /************* 66 | ** Now we have populated the classMI array, and selected the highest 67 | ** MI feature as the first output feature 68 | ** Now we move into the mRMR-D algorithm 69 | *************/ 70 | 71 | for (i = 1; i < k; i++) 72 | { 73 | /*to ensure it selects some features 74 | **if this is zero then it will not pick features where the redundancy is greater than the 75 | **relevance 76 | */ 77 | score = -1000.0; 78 | currentHighestFeature = 0; 79 | currentScore = 0.0; 80 | totalFeatureMI = 0.0; 81 | 82 | for (j = 0; j < noOfFeatures; j++) 83 | { 84 | /*if we haven't selected j*/ 85 | if (selectedFeatures[j] == 0) 86 | { 87 | currentScore = classMI[j]; 88 | totalFeatureMI = 0.0; 89 | 90 | for (x = 0; x < i; x++) 91 | { 92 | arrayPosition = x*noOfFeatures + j; 93 | if (featureMIMatrix[arrayPosition] == -1) 94 | { 95 | /*work out intra MI*/ 96 | 97 | /*double discAndCalcMutualInformation(double *firstVector, double *secondVector, int vectorLength);*/ 98 | featureMIMatrix[arrayPosition] = discAndCalcMutualInformation(feature2D[(int) outputFeatures[x]], feature2D[j], noOfSamples); 99 | } 100 | 101 | totalFeatureMI += featureMIMatrix[arrayPosition]; 102 | }/*for the number of already selected features*/ 103 | 104 | currentScore -= (totalFeatureMI/i); 105 | if (currentScore > score) 106 | { 107 | score = currentScore; 108 | currentHighestFeature = j; 109 | } 110 | }/*if j is unselected*/ 111 | }/*for number of features*/ 112 | 113 | selectedFeatures[currentHighestFeature] = 1; 114 | outputFeatures[i] = currentHighestFeature; 115 | 116 | }/*for the number of features to select*/ 117 | 118 | for (i = 0; i < k; i++) 119 | { 120 | outputFeatures[i] += 1; /*C indexes from 0 not 1*/ 121 | }/*for number of selected features*/ 122 | 123 | }/*mRMRCalculation(double[][],double[])*/ 124 | 125 | /*entry point for the mex call 126 | **nlhs - number of outputs 127 | **plhs - pointer to array of outputs 128 | **nrhs - number of inputs 129 | **prhs - pointer to array of inputs 130 | */ 131 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 132 | { 133 | /************************************************************* 134 | ** this function takes 3 arguments: 135 | ** k = number of features to select, 136 | ** featureMatrix[][] = matrix of features 137 | ** classColumn[] = targets 138 | ** the arguments should all be discrete integers. 139 | ** and has one output: 140 | ** selectedFeatures[] of size k 141 | *************************************************************/ 142 | 143 | int k, numberOfFeatures, numberOfSamples, numberOfTargets; 144 | double *featureMatrix, *targets, *output; 145 | 146 | 147 | if (nlhs != 1) 148 | { 149 | printf("Incorrect number of output arguments"); 150 | }/*if not 1 output*/ 151 | if (nrhs != 3) 152 | { 153 | printf("Incorrect number of input arguments"); 154 | }/*if not 3 inputs*/ 155 | 156 | /*get the number of features to select, cast out as it is a double*/ 157 | k = (int) mxGetScalar(prhs[0]); 158 | 159 | numberOfFeatures = mxGetN(prhs[1]); 160 | numberOfSamples = mxGetM(prhs[1]); 161 | 162 | numberOfTargets = mxGetM(prhs[2]); 163 | 164 | if (numberOfTargets != numberOfSamples) 165 | { 166 | printf("Number of targets must match number of samples\n"); 167 | printf("Number of targets = %d, Number of Samples = %d, Number of Features = %d\n",numberOfTargets,numberOfSamples,numberOfFeatures); 168 | 169 | plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); 170 | }/*if size mismatch*/ 171 | else 172 | { 173 | 174 | featureMatrix = mxGetPr(prhs[1]); 175 | targets = mxGetPr(prhs[2]); 176 | 177 | plhs[0] = mxCreateDoubleMatrix(k,1,mxREAL); 178 | output = (double *)mxGetPr(plhs[0]); 179 | 180 | /*void mRMRCalculation(int k, int noOfSamples, int noOfFeatures,double *featureMatrix, double *classColumn, double *outputFeatures)*/ 181 | mRMRCalculation(k,numberOfSamples,numberOfFeatures,featureMatrix,targets,output); 182 | } 183 | 184 | return; 185 | }/*mexFunction()*/ 186 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/h.m: -------------------------------------------------------------------------------- 1 | function output = h(X) 2 | %function output = h(X) 3 | %X can be a matrix which is converted into a joint variable before calculation 4 | %expects variables to be column-wise 5 | % 6 | %returns the entropy of X, H(X) 7 | 8 | if (~isa(X,'double')) 9 | error('Error, inputs must be double vectors or matrices') 10 | end 11 | if (size(X,2)>1) 12 | mergedVector = MIToolboxMex(3,X); 13 | else 14 | mergedVector = X; 15 | end 16 | [output] = MIToolboxMex(4,mergedVector); 17 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/joint.m: -------------------------------------------------------------------------------- 1 | function output = joint(X,arities) 2 | %function output = joint(X,arities) 3 | %returns the joint random variable of the matrix X 4 | %assuming the variables are in columns 5 | % 6 | %if passed a vector of the arities then it produces a correct 7 | %joint variable, otherwise it may not include all states 8 | % 9 | %if the joint variable is only compared with variables using the same samples, 10 | %then arity information is not required 11 | 12 | if (nargin == 2) 13 | if (~isa(X,'double') || ~isa(arities,'double')) 14 | error('Error, inputs must be double vectors or matrices') 15 | end 16 | [output] = MIToolboxMex(3,X,arities); 17 | else 18 | if (~isa(X,'double')) 19 | error('Error, input must be a double vector or matrix') 20 | end 21 | [output] = MIToolboxMex(3,X); 22 | end 23 | -------------------------------------------------------------------------------- /MIToolbox-master/matlab/mi.m: -------------------------------------------------------------------------------- 1 | function output = mi(X,Y) 2 | %function output = mi(X,Y) 3 | %X & Y can be matrices which are converted into a joint variable 4 | %before computation 5 | % 6 | %expects variables to be column-wise 7 | % 8 | %returns the mutual information between X and Y, I(X;Y) 9 | 10 | if (~isa(X,'double') || ~isa(Y,'double')) 11 | error('Error, inputs must be double vectors or matrices') 12 | end 13 | if (size(X,2)>1) 14 | mergedFirst = MIToolboxMex(3,X); 15 | else 16 | mergedFirst = X; 17 | end 18 | if (size(Y,2)>1) 19 | mergedSecond = MIToolboxMex(3,Y); 20 | else 21 | mergedSecond = Y; 22 | end 23 | [output] = MIToolboxMex(7,mergedFirst,mergedSecond); 24 | -------------------------------------------------------------------------------- /MIToolbox-master/src/Entropy.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** Entropy.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the entropy of a single variable H(X), 6 | ** the joint entropy of two variables H(X,Y), and the conditional entropy 7 | ** H(X|Y) 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 19/2/2010 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | ******************************************************************************/ 17 | 18 | #include "MIToolbox/MIToolbox.h" 19 | #include "MIToolbox/CalculateProbability.h" 20 | #include "MIToolbox/Entropy.h" 21 | 22 | double entropy(ProbabilityState state) { 23 | double entropy = 0.0; 24 | double tempValue = 0.0; 25 | int i; 26 | 27 | /*H(X) = - \sum p(x) \log p(x)*/ 28 | for (i = 0; i < state.numStates; i++) { 29 | tempValue = state.probabilityVector[i]; 30 | 31 | if (tempValue > 0) { 32 | entropy -= tempValue * log(tempValue); 33 | } 34 | } 35 | 36 | entropy /= log(LOG_BASE); 37 | 38 | return entropy; 39 | } 40 | 41 | double discAndCalcEntropy(double* dataVector, int vectorLength) { 42 | ProbabilityState state = discAndCalcProbability(dataVector, vectorLength); 43 | double h = entropy(state); 44 | 45 | freeProbabilityState(state); 46 | 47 | return h; 48 | }/*discAndCalcEntropy(double* ,int)*/ 49 | 50 | double calcEntropy(uint* dataVector, int vectorLength) { 51 | ProbabilityState state = calculateProbability(dataVector, vectorLength); 52 | double h = entropy(state); 53 | 54 | freeProbabilityState(state); 55 | 56 | return h; 57 | }/*calcEntropy(uint* ,int)*/ 58 | 59 | double jointEntropy(JointProbabilityState state) { 60 | double jointEntropy = 0.0; 61 | double tempValue = 0.0; 62 | int i; 63 | 64 | /*H(XY) = - \sum_x \sum_y p(xy) \log p(xy)*/ 65 | for (i = 0; i < state.numJointStates; i++) { 66 | tempValue = state.jointProbabilityVector[i]; 67 | if (tempValue > 0) { 68 | jointEntropy -= tempValue * log(tempValue); 69 | } 70 | } 71 | 72 | jointEntropy /= log(LOG_BASE); 73 | 74 | return jointEntropy; 75 | } 76 | 77 | double discAndCalcJointEntropy(double *firstVector, double *secondVector, int vectorLength) { 78 | JointProbabilityState state = discAndCalcJointProbability(firstVector, secondVector, vectorLength); 79 | double h = jointEntropy(state); 80 | 81 | freeJointProbabilityState(state); 82 | 83 | return h; 84 | }/*discAndCalcJointEntropy(double *, double *, int)*/ 85 | 86 | double calcJointEntropy(uint *firstVector, uint *secondVector, int vectorLength) { 87 | JointProbabilityState state = calculateJointProbability(firstVector, secondVector, vectorLength); 88 | double h = jointEntropy(state); 89 | 90 | freeJointProbabilityState(state); 91 | 92 | return h; 93 | }/*calcJointEntropy(uint *, uint *, int)*/ 94 | 95 | double condEntropy(JointProbabilityState state) { 96 | double condEntropy = 0.0; 97 | double jointValue = 0.0; 98 | double condValue = 0.0; 99 | int i; 100 | 101 | /*H(X|Y) = - \sum_x \sum_y p(x,y) \log p(x,y)/p(y)*/ 102 | /** Indexing by numFirstStates use modulus of i 103 | ** Indexing by numSecondStates use integer division of i by numFirstStates*/ 104 | for (i = 0; i < state.numJointStates; i++) { 105 | jointValue = state.jointProbabilityVector[i]; 106 | condValue = state.secondProbabilityVector[i / state.numFirstStates]; 107 | if ((jointValue > 0) && (condValue > 0)) { 108 | condEntropy -= jointValue * log(jointValue / condValue); 109 | } 110 | } 111 | 112 | condEntropy /= log(LOG_BASE); 113 | 114 | return condEntropy; 115 | } 116 | 117 | double discAndCalcConditionalEntropy(double *dataVector, double *conditionVector, int vectorLength) { 118 | JointProbabilityState state = discAndCalcJointProbability(dataVector, conditionVector, vectorLength); 119 | double h = condEntropy(state); 120 | 121 | freeJointProbabilityState(state); 122 | 123 | return h; 124 | }/*discAndCalcConditionalEntropy(double *, double *, int)*/ 125 | 126 | double calcConditionalEntropy(uint *dataVector, uint *conditionVector, int vectorLength) { 127 | JointProbabilityState state = calculateJointProbability(dataVector, conditionVector, vectorLength); 128 | double h = condEntropy(state); 129 | 130 | freeJointProbabilityState(state); 131 | 132 | return h; 133 | }/*calcConditionalEntropy(uint *, uint *, int)*/ 134 | 135 | -------------------------------------------------------------------------------- /MIToolbox-master/src/MutualInformation.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** MutualInformation.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the mutual information of 6 | ** two variables X and Y, I(X;Y), to calculate the joint mutual information 7 | ** of two variables X & Z on the variable Y, I(XZ;Y), and the conditional 8 | ** mutual information I(x;Y|Z) 9 | ** 10 | ** Author: Adam Pocock 11 | ** Created 19/2/2010 12 | ** Updated - 22/02/2014 - Added checking on calloc. 13 | ** 14 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 15 | ** www.cs.manchester.ac.uk 16 | ** 17 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 18 | *******************************************************************************/ 19 | 20 | #include "MIToolbox/MIToolbox.h" 21 | #include "MIToolbox/ArrayOperations.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | #include "MIToolbox/Entropy.h" 24 | #include "MIToolbox/MutualInformation.h" 25 | 26 | double mi(JointProbabilityState state) { 27 | double mutualInformation = 0.0; 28 | int firstIndex,secondIndex; 29 | int i; 30 | 31 | /* 32 | ** I(X;Y) = \sum_x \sum_y p(x,y) * \log (p(x,y)/p(x)p(y)) 33 | */ 34 | for (i = 0; i < state.numJointStates; i++) { 35 | firstIndex = i % state.numFirstStates; 36 | secondIndex = i / state.numFirstStates; 37 | 38 | if ((state.jointProbabilityVector[i] > 0) && (state.firstProbabilityVector[firstIndex] > 0) && (state.secondProbabilityVector[secondIndex] > 0)) { 39 | /*double division is probably more stable than multiplying two small numbers together 40 | ** mutualInformation += state.jointProbabilityVector[i] * log(state.jointProbabilityVector[i] / (state.firstProbabilityVector[firstIndex] * state.secondProbabilityVector[secondIndex])); 41 | */ 42 | mutualInformation += state.jointProbabilityVector[i] * log(state.jointProbabilityVector[i] / state.firstProbabilityVector[firstIndex] / state.secondProbabilityVector[secondIndex]); 43 | } 44 | } 45 | 46 | mutualInformation /= log(LOG_BASE); 47 | 48 | return mutualInformation; 49 | }/*mi(JointProbabilityState)*/ 50 | 51 | double calcMutualInformation(uint *dataVector, uint *targetVector, int vectorLength) { 52 | JointProbabilityState state = calculateJointProbability(dataVector,targetVector,vectorLength); 53 | 54 | double mutualInformation = mi(state); 55 | 56 | freeJointProbabilityState(state); 57 | 58 | return mutualInformation; 59 | }/*calculateMutualInformation(uint *,uint *,int)*/ 60 | 61 | double discAndCalcMutualInformation(double *dataVector, double *targetVector, int vectorLength) { 62 | JointProbabilityState state = discAndCalcJointProbability(dataVector,targetVector,vectorLength); 63 | 64 | double mutualInformation = mi(state); 65 | 66 | freeJointProbabilityState(state); 67 | 68 | return mutualInformation; 69 | }/*discAndCalcMutualInformation(double *,double *,int)*/ 70 | 71 | double calcConditionalMutualInformation(uint *dataVector, uint *targetVector, uint *conditionVector, int vectorLength) { 72 | double mutualInformation = 0.0; 73 | double firstCondition, secondCondition; 74 | uint *mergedVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 75 | 76 | mergeArrays(targetVector,conditionVector,mergedVector,vectorLength); 77 | 78 | /* I(X;Y|Z) = H(X|Z) - H(X|YZ) */ 79 | /* double calculateConditionalEntropy(double *dataVector, double *conditionVector, int vectorLength); */ 80 | firstCondition = calcConditionalEntropy(dataVector,conditionVector,vectorLength); 81 | secondCondition = calcConditionalEntropy(dataVector,mergedVector,vectorLength); 82 | 83 | mutualInformation = firstCondition - secondCondition; 84 | 85 | FREE_FUNC(mergedVector); 86 | mergedVector = NULL; 87 | 88 | return mutualInformation; 89 | }/*calculateConditionalMutualInformation(double *,double *,double *,int)*/ 90 | 91 | double discAndCalcConditionalMutualInformation(double *dataVector, double *targetVector, double *conditionVector, int vectorLength) { 92 | double mutualInformation = 0.0; 93 | double firstCondition, secondCondition; 94 | uint *dataNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 95 | uint *targetNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 96 | uint *conditionNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 97 | uint *mergedVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 98 | 99 | normaliseArray(dataVector,dataNormVector,vectorLength); 100 | normaliseArray(targetVector,targetNormVector,vectorLength); 101 | normaliseArray(conditionVector,conditionNormVector,vectorLength); 102 | mergeArrays(targetNormVector,conditionNormVector,mergedVector,vectorLength); 103 | 104 | /* I(X;Y|Z) = H(X|Z) - H(X|YZ) */ 105 | /* double calculateConditionalEntropy(double *dataVector, double *conditionVector, int vectorLength); */ 106 | firstCondition = calcConditionalEntropy(dataNormVector,conditionNormVector,vectorLength); 107 | secondCondition = calcConditionalEntropy(dataNormVector,mergedVector,vectorLength); 108 | 109 | mutualInformation = firstCondition - secondCondition; 110 | 111 | FREE_FUNC(dataNormVector); 112 | FREE_FUNC(targetNormVector); 113 | FREE_FUNC(conditionNormVector); 114 | FREE_FUNC(mergedVector); 115 | dataNormVector = NULL; 116 | targetNormVector = NULL; 117 | conditionNormVector = NULL; 118 | mergedVector = NULL; 119 | 120 | return mutualInformation; 121 | }/*calculateConditionalMutualInformation(double *,double *,double *,int)*/ 122 | -------------------------------------------------------------------------------- /MIToolbox-master/src/RenyiEntropy.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** RenyiEntropy.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the Renyi alpha entropy of a single variable 6 | ** H_\alpha(X), the Renyi joint entropy of two variables H_\alpha(X,Y), and the 7 | ** conditional Renyi entropy H_\alpha(X|Y) 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 26/3/2010 11 | ** Updated - 22/02/2014 - Added checking on calloc. 12 | ** 13 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 14 | ** www.cs.manchester.ac.uk 15 | ** 16 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 17 | *******************************************************************************/ 18 | 19 | #include "MIToolbox/MIToolbox.h" 20 | #include "MIToolbox/ArrayOperations.h" 21 | #include "MIToolbox/CalculateProbability.h" 22 | #include "MIToolbox/Entropy.h" 23 | 24 | double renyiEntropy(ProbabilityState state, double alpha) { 25 | double entropy = 0.0; 26 | double tempValue = 0.0; 27 | int i; 28 | 29 | /*H_\alpha(X) = 1/(1-alpha) * \log(\sum_x p(x)^alpha)*/ 30 | for (i = 0; i < state.numStates; i++) { 31 | tempValue = state.probabilityVector[i]; 32 | if (tempValue > 0) { 33 | entropy += pow(tempValue,alpha); 34 | } 35 | } 36 | 37 | entropy = log(entropy); 38 | entropy /= log(LOG_BASE); 39 | entropy /= (1.0-alpha); 40 | 41 | return entropy; 42 | } 43 | 44 | double calcRenyiEntropy(double alpha, uint *dataVector, int vectorLength) { 45 | ProbabilityState state = calculateProbability(dataVector,vectorLength); 46 | double h = renyiEntropy(state,alpha); 47 | 48 | freeProbabilityState(state); 49 | 50 | return h; 51 | }/*calcRenyiEntropy(double,uint*,int)*/ 52 | 53 | double discAndCalcRenyiEntropy(double alpha, double *dataVector, int vectorLength) { 54 | ProbabilityState state = discAndCalcProbability(dataVector,vectorLength); 55 | double h = renyiEntropy(state,alpha); 56 | 57 | freeProbabilityState(state); 58 | 59 | return h; 60 | }/*discAndCalcRenyiEntropy(double,double*,int)*/ 61 | 62 | double jointRenyiEntropy(JointProbabilityState state, double alpha) { 63 | double jointEntropy = 0.0; 64 | double tempValue = 0.0; 65 | int i; 66 | 67 | /*H_\alpha(XY) = 1/(1-alpha) * log(2)(sum p(xy)^alpha)*/ 68 | for (i = 0; i < state.numJointStates; i++) { 69 | tempValue = state.jointProbabilityVector[i]; 70 | if (tempValue > 0) { 71 | jointEntropy += pow(tempValue,alpha); 72 | } 73 | } 74 | 75 | jointEntropy = log(jointEntropy); 76 | jointEntropy /= log(LOG_BASE); 77 | jointEntropy /= (1.0-alpha); 78 | 79 | return jointEntropy; 80 | } 81 | 82 | double calcJointRenyiEntropy(double alpha, uint *firstVector, uint *secondVector, int vectorLength) { 83 | JointProbabilityState state = calculateJointProbability(firstVector,secondVector,vectorLength); 84 | double h = jointRenyiEntropy(state,alpha); 85 | 86 | freeJointProbabilityState(state); 87 | 88 | return h; 89 | }/*calcJointRenyiEntropy(double,uint*,uint*,int)*/ 90 | 91 | double discAndCalcJointRenyiEntropy(double alpha, double *firstVector, double *secondVector, int vectorLength) { 92 | JointProbabilityState state = discAndCalcJointProbability(firstVector,secondVector,vectorLength); 93 | double h = jointRenyiEntropy(state,alpha); 94 | 95 | freeJointProbabilityState(state); 96 | 97 | return h; 98 | }/*discAndCalcJointRenyiEntropy(double,double*,double*,int)*/ 99 | -------------------------------------------------------------------------------- /MIToolbox-master/src/RenyiMutualInformation.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** RenyiMutualInformation.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the Renyi mutual information of 6 | ** two variables X and Y, I_\alpha(X;Y), using the Renyi alpha divergence and 7 | ** the joint entropy difference 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created 26/3/2010 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #include "MIToolbox/MIToolbox.h" 19 | #include "MIToolbox/ArrayOperations.h" 20 | #include "MIToolbox/CalculateProbability.h" 21 | #include "MIToolbox/RenyiEntropy.h" 22 | #include "MIToolbox/RenyiMutualInformation.h" 23 | 24 | double renyiMI(JointProbabilityState state, double alpha) { 25 | int firstIndex,secondIndex; 26 | int i; 27 | double jointTemp, marginalTemp; 28 | double invAlpha = 1.0 - alpha; 29 | double mutualInformation = 0.0; 30 | 31 | /* standard MI is D_KL(p(x,y)||p(x)p(y)) 32 | ** which expands to 33 | ** D_KL(p(x,y)||p(x)p(y)) = sum(p(x,y) * log(p(x,y)/(p(x)p(y)))) 34 | ** 35 | ** Renyi alpha divergence D_alpha(p(x,y)||p(x)p(y)) 36 | ** expands to 37 | ** D_alpha(p(x,y)||p(x)p(y)) = 1/(alpha-1) * log(sum((p(x,y)^alpha)*((p(x)p(y))^(1-alpha)))) 38 | */ 39 | 40 | for (i = 0; i < state.numJointStates; i++) { 41 | firstIndex = i % state.numFirstStates; 42 | secondIndex = i / state.numFirstStates; 43 | 44 | if ((state.jointProbabilityVector[i] > 0) && (state.firstProbabilityVector[firstIndex] > 0) && (state.secondProbabilityVector[secondIndex] > 0)) { 45 | jointTemp = pow(state.jointProbabilityVector[i],alpha); 46 | marginalTemp = state.firstProbabilityVector[firstIndex] * state.secondProbabilityVector[secondIndex]; 47 | marginalTemp = pow(marginalTemp,invAlpha); 48 | mutualInformation += (jointTemp * marginalTemp); 49 | } 50 | } 51 | 52 | mutualInformation = log(mutualInformation); 53 | mutualInformation /= log(LOG_BASE); 54 | mutualInformation /= (alpha-1.0); 55 | 56 | return mutualInformation; 57 | } 58 | 59 | double calcRenyiMIDivergence(double alpha, uint *dataVector, uint *targetVector, int vectorLength) { 60 | JointProbabilityState state = calculateJointProbability(dataVector,targetVector,vectorLength); 61 | double mutualInformation = renyiMI(state,alpha); 62 | 63 | freeJointProbabilityState(state); 64 | 65 | return mutualInformation; 66 | }/*calcRenyiMIDivergence(double, uint *, uint *, int)*/ 67 | 68 | double discAndCalcRenyiMIDivergence(double alpha, double *dataVector, double *targetVector, int vectorLength) { 69 | JointProbabilityState state = discAndCalcJointProbability(dataVector,targetVector,vectorLength); 70 | double mutualInformation = renyiMI(state,alpha); 71 | 72 | freeJointProbabilityState(state); 73 | 74 | return mutualInformation; 75 | }/*discAndCalcRenyiMIDivergence(double, double *, double *, int)*/ 76 | 77 | double calcRenyiMIJoint(double alpha, uint *dataVector, uint *targetVector, int vectorLength) { 78 | double hY = calcRenyiEntropy(alpha, targetVector, vectorLength); 79 | double hX = calcRenyiEntropy(alpha, dataVector, vectorLength); 80 | 81 | double hXY = calcJointRenyiEntropy(alpha, dataVector, targetVector, vectorLength); 82 | 83 | double answer = hX + hY - hXY; 84 | 85 | return answer; 86 | }/*calcRenyiMIJoint(double, uint*, uint*, int)*/ 87 | 88 | double discAndCalcRenyiMIJoint(double alpha, double *dataVector, double *targetVector, int vectorLength) { 89 | double mi; 90 | uint *dataNormVector = (uint *) checkedCalloc(vectorLength, sizeof(uint)); 91 | uint *targetNormVector = (uint *) checkedCalloc(vectorLength, sizeof(uint)); 92 | 93 | normaliseArray(dataVector,dataNormVector,vectorLength); 94 | normaliseArray(targetVector,targetNormVector,vectorLength); 95 | 96 | mi = calcRenyiMIJoint(alpha,dataNormVector,targetNormVector,vectorLength); 97 | 98 | FREE_FUNC(dataNormVector); 99 | FREE_FUNC(targetNormVector); 100 | dataNormVector = NULL; 101 | targetNormVector = NULL; 102 | 103 | return mi; 104 | }/*discAndCalcRenyiMIJoint(double, double*, double*, int)*/ 105 | -------------------------------------------------------------------------------- /MIToolbox-master/src/WeightedEntropy.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** WeightedEntropy.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the entropy of a single variable H(X), 6 | ** the joint entropy of two variables H(X,Y), and the conditional entropy 7 | ** H(X|Y), while using a weight vector to modify the calculation. 8 | ** 9 | ** Author: Adam Pocock 10 | ** Created: 20/06/2011 11 | ** 12 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 13 | ** www.cs.manchester.ac.uk 14 | ** 15 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 16 | *******************************************************************************/ 17 | 18 | #include "MIToolbox/MIToolbox.h" 19 | #include "MIToolbox/CalculateProbability.h" 20 | #include "MIToolbox/WeightedEntropy.h" 21 | 22 | double wEntropy(WeightedProbState state) { 23 | double entropy = 0.0; 24 | double tempValue = 0.0; 25 | int i; 26 | 27 | /*H_w(X) = - \sum_x w(x)p(x) \log p(x)*/ 28 | for (i = 0; i < state.numStates; i++) { 29 | tempValue = state.probabilityVector[i]; 30 | if (tempValue > 0) { 31 | entropy -= state.stateWeightVector[i] * tempValue * log(tempValue); 32 | } 33 | } 34 | 35 | entropy /= log(LOG_BASE); 36 | 37 | return entropy; 38 | } 39 | 40 | double calcWeightedEntropy(uint *dataVector, double *weightVector, int vectorLength) { 41 | WeightedProbState state = calculateWeightedProbability(dataVector,weightVector,vectorLength); 42 | double entropy = wEntropy(state); 43 | 44 | freeWeightedProbState(state); 45 | 46 | return entropy; 47 | }/*calcWeightedEntropy(uint *,double *,int)*/ 48 | 49 | double discAndCalcWeightedEntropy(double *dataVector, double *weightVector, int vectorLength) { 50 | WeightedProbState state = discAndCalcWeightedProbability(dataVector,weightVector,vectorLength); 51 | double entropy = wEntropy(state); 52 | 53 | freeWeightedProbState(state); 54 | 55 | return entropy; 56 | }/*discAndCalcWeightedEntropy(double *,double *,int)*/ 57 | 58 | double wJointEntropy(WeightedJointProbState state) { 59 | double jointEntropy = 0.0; 60 | double tempValue = 0.0; 61 | int i; 62 | 63 | /*H_w(X,Y) = - \sum_x \sum_y w(x,y) p(x,y) \log p(x,y)*/ 64 | for (i = 0; i < state.numJointStates; i++) { 65 | tempValue = state.jointProbabilityVector[i]; 66 | if (tempValue > 0) { 67 | jointEntropy -= state.jointWeightVector[i] * tempValue * log(tempValue); 68 | } 69 | } 70 | 71 | jointEntropy /= log(LOG_BASE); 72 | 73 | return jointEntropy; 74 | } 75 | 76 | double calcWeightedJointEntropy(uint *firstVector, uint *secondVector, double *weightVector, int vectorLength) { 77 | WeightedJointProbState state = calculateWeightedJointProbability(firstVector,secondVector,weightVector,vectorLength); 78 | double jointEntropy = wJointEntropy(state); 79 | 80 | freeWeightedJointProbState(state); 81 | 82 | return jointEntropy; 83 | }/*calcWeightedJointEntropy(uint *,uint *,double *,int)*/ 84 | 85 | double discAndCalcWeightedJointEntropy(double *firstVector, double *secondVector, double *weightVector, int vectorLength) { 86 | WeightedJointProbState state = discAndCalcWeightedJointProbability(firstVector,secondVector,weightVector,vectorLength); 87 | double jointEntropy = wJointEntropy(state); 88 | 89 | freeWeightedJointProbState(state); 90 | 91 | return jointEntropy; 92 | }/*discAndCalcWeightedJointEntropy(double *,double *,double *,int)*/ 93 | 94 | double wCondEntropy(WeightedJointProbState state) { 95 | double condEntropy = 0.0; 96 | double jointValue = 0.0; 97 | double condValue = 0.0; 98 | int i; 99 | 100 | /*H_w(X|Y) = - \sum_x \sum_y w(x,y)p(x,y) \log (p(x,y)/p(y))*/ 101 | /* to index by numFirstStates use modulus of i 102 | ** to index by numSecondStates use integer division of i by numFirstStates 103 | */ 104 | for (i = 0; i < state.numJointStates; i++) { 105 | jointValue = state.jointProbabilityVector[i]; 106 | condValue = state.secondProbabilityVector[i / state.numFirstStates]; 107 | if ((jointValue > 0) && (condValue > 0)) { 108 | condEntropy -= state.jointWeightVector[i] * jointValue * log(jointValue / condValue); 109 | } 110 | } 111 | 112 | condEntropy /= log(LOG_BASE); 113 | 114 | return condEntropy; 115 | } 116 | 117 | double calcWeightedConditionalEntropy(uint *dataVector, uint *conditionVector, double *weightVector, int vectorLength) { 118 | WeightedJointProbState state = calculateWeightedJointProbability(dataVector,conditionVector,weightVector,vectorLength); 119 | double condEntropy = wCondEntropy(state); 120 | 121 | freeWeightedJointProbState(state); 122 | 123 | return condEntropy; 124 | }/*calcWeightedConditionalEntropy(uint *,uint *,double *,int)*/ 125 | 126 | double discAndCalcWeightedConditionalEntropy(double *dataVector, double *conditionVector, double *weightVector, int vectorLength) { 127 | WeightedJointProbState state = discAndCalcWeightedJointProbability(dataVector,conditionVector,weightVector,vectorLength); 128 | double condEntropy = wCondEntropy(state); 129 | 130 | freeWeightedJointProbState(state); 131 | 132 | return condEntropy; 133 | }/*discAndCalcWeightedConditionalEntropy(double *,double *,double *,int)*/ 134 | -------------------------------------------------------------------------------- /MIToolbox-master/src/WeightedMutualInformation.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | ** WeightedMutualInformation.c 3 | ** Part of the mutual information toolbox 4 | ** 5 | ** Contains functions to calculate the mutual information of 6 | ** two variables X and Y, I(X;Y), to calculate the joint mutual information 7 | ** of two variables X & Z on the variable Y, I(XZ;Y), and the conditional 8 | ** mutual information I(X;Y|Z), while using a weight vector to modify the 9 | ** calculation. 10 | ** 11 | ** Author: Adam Pocock 12 | ** Created: 20/06/2011 13 | ** 14 | ** Copyright 2010-2017 Adam Pocock, The University Of Manchester 15 | ** www.cs.manchester.ac.uk 16 | ** 17 | ** This file is part of MIToolbox, licensed under the 3-clause BSD license. 18 | *******************************************************************************/ 19 | 20 | #include "MIToolbox/MIToolbox.h" 21 | #include "MIToolbox/ArrayOperations.h" 22 | #include "MIToolbox/CalculateProbability.h" 23 | #include "MIToolbox/WeightedEntropy.h" 24 | #include "MIToolbox/WeightedMutualInformation.h" 25 | 26 | double wmi(WeightedJointProbState state) { 27 | double mutualInformation = 0.0; 28 | int firstIndex,secondIndex; 29 | int i; 30 | 31 | /* 32 | ** I_w(X;Y) = \sum_x \sum_y w(x,y)p(x,y) * \log (p(x,y)/p(x)p(y)) 33 | */ 34 | for (i = 0; i < state.numJointStates; i++) { 35 | firstIndex = i % state.numFirstStates; 36 | secondIndex = i / state.numFirstStates; 37 | 38 | if ((state.jointProbabilityVector[i] > 0) && (state.firstProbabilityVector[firstIndex] > 0) && (state.secondProbabilityVector[secondIndex] > 0)) { 39 | mutualInformation += state.jointWeightVector[i] * state.jointProbabilityVector[i] * log(state.jointProbabilityVector[i] / state.firstProbabilityVector[firstIndex] / state.secondProbabilityVector[secondIndex]); 40 | } 41 | } 42 | 43 | mutualInformation /= log(LOG_BASE); 44 | 45 | return mutualInformation; 46 | } 47 | 48 | double calcWeightedMutualInformation(uint *dataVector, uint *targetVector, double *weightVector, int vectorLength) { 49 | WeightedJointProbState state = calculateWeightedJointProbability(dataVector,targetVector,weightVector,vectorLength); 50 | double mutualInformation = wmi(state); 51 | 52 | freeWeightedJointProbState(state); 53 | 54 | return mutualInformation; 55 | }/*calcWeightedMutualInformation(uint *,uint *,double *,int)*/ 56 | 57 | double discAndCalcWeightedMutualInformation(double *dataVector, double *targetVector, double *weightVector, int vectorLength) { 58 | WeightedJointProbState state = discAndCalcWeightedJointProbability(dataVector,targetVector,weightVector,vectorLength); 59 | double mutualInformation = wmi(state); 60 | 61 | freeWeightedJointProbState(state); 62 | 63 | return mutualInformation; 64 | }/*discAndCalcWeightedMutualInformation(double *,double *,double *,int)*/ 65 | 66 | double calcWeightedConditionalMutualInformation(uint *dataVector, uint *targetVector, uint *conditionVector, double *weightVector, int vectorLength) { 67 | double mutualInformation = 0.0; 68 | double firstCondition, secondCondition; 69 | uint *mergedVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 70 | 71 | mergeArrays(targetVector,conditionVector,mergedVector,vectorLength); 72 | 73 | /* I(X;Y|Z) = H(X|Z) - H(X|YZ) */ 74 | /* double calculateWeightedConditionalEntropy(double *dataVector, double *conditionVector, double *weightVector, int vectorLength); */ 75 | firstCondition = calcWeightedConditionalEntropy(dataVector,conditionVector,weightVector,vectorLength); 76 | secondCondition = calcWeightedConditionalEntropy(dataVector,mergedVector,weightVector,vectorLength); 77 | 78 | mutualInformation = firstCondition - secondCondition; 79 | 80 | FREE_FUNC(mergedVector); 81 | mergedVector = NULL; 82 | 83 | return mutualInformation; 84 | }/*calcWeightedConditionalMutualInformation(double *,double *,double *,double *,int)*/ 85 | 86 | double discAndCalcWeightedConditionalMutualInformation(double *dataVector, double *targetVector, double *conditionVector, double *weightVector, int vectorLength) { 87 | double mutualInformation = 0.0; 88 | double firstCondition, secondCondition; 89 | uint *dataNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 90 | uint *targetNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 91 | uint *conditionNormVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 92 | uint *mergedVector = (uint *) checkedCalloc(vectorLength,sizeof(uint)); 93 | 94 | normaliseArray(dataVector,dataNormVector,vectorLength); 95 | normaliseArray(targetVector,targetNormVector,vectorLength); 96 | normaliseArray(conditionVector,conditionNormVector,vectorLength); 97 | mergeArrays(targetNormVector,conditionNormVector,mergedVector,vectorLength); 98 | 99 | /* I_w(X;Y|Z) = H_w(X|Z) - H_w(X|YZ) */ 100 | /* double calculateWeightedConditionalEntropy(double *dataVector, double *conditionVector, double *weightVector, int vectorLength); */ 101 | firstCondition = calcWeightedConditionalEntropy(dataNormVector,conditionNormVector,weightVector,vectorLength); 102 | secondCondition = calcWeightedConditionalEntropy(dataNormVector,mergedVector,weightVector,vectorLength); 103 | 104 | mutualInformation = firstCondition - secondCondition; 105 | 106 | FREE_FUNC(dataNormVector); 107 | FREE_FUNC(targetNormVector); 108 | FREE_FUNC(conditionNormVector); 109 | FREE_FUNC(mergedVector); 110 | dataNormVector = NULL; 111 | targetNormVector = NULL; 112 | conditionNormVector = NULL; 113 | mergedVector = NULL; 114 | 115 | return mutualInformation; 116 | }/*discAndCalcWeightedConditionalMutualInformation(double *,double *,double *,double *,int)*/ 117 | -------------------------------------------------------------------------------- /MIToolbox-master/test/testMIToolbox.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "MIToolbox/ArrayOperations.h" 6 | #include "MIToolbox/Entropy.h" 7 | #include "MIToolbox/MutualInformation.h" 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | int i; 12 | double length, miTarget, entropyTarget, cmiTarget; 13 | double firstEntropy, secondEntropy, thirdEntropy, targetEntropy; 14 | double firstMItarget, secondMItarget, thirdMItarget, targetMItarget; 15 | int *testFirstVector, *testSecondVector, *testThirdVector, *testMergedVector; 16 | struct timeval start,end; 17 | 18 | int *firstVector = (int *) calloc(4,sizeof(int)); 19 | int *secondVector = (int *) calloc(4,sizeof(int)); 20 | int *thirdVector = (int *) calloc(4,sizeof(int)); 21 | int *targetVector = (int *) calloc(4,sizeof(int)); 22 | 23 | firstVector[0] = 0; 24 | firstVector[1] = 0; 25 | firstVector[2] = 1; 26 | firstVector[3] = 1; 27 | 28 | secondVector[0] = 0; 29 | secondVector[1] = 1; 30 | secondVector[2] = 0; 31 | secondVector[3] = 1; 32 | 33 | thirdVector[0] = 0; 34 | thirdVector[1] = 1; 35 | thirdVector[2] = 1; 36 | thirdVector[3] = 1; 37 | 38 | targetVector[0] = 0; 39 | targetVector[1] = 1; 40 | targetVector[2] = 1; 41 | targetVector[3] = 0; 42 | 43 | firstEntropy = calcEntropy(firstVector,4); 44 | secondEntropy = calcEntropy(secondVector,4); 45 | thirdEntropy = calcEntropy(thirdVector,4); 46 | targetEntropy = calcEntropy(targetVector,4); 47 | 48 | printf("Entropies - first: %f, second: %f, third: %f, target %f\n",firstEntropy,secondEntropy,thirdEntropy,targetEntropy); 49 | 50 | firstMItarget = calcMutualInformation(firstVector,targetVector,4); 51 | secondMItarget = calcMutualInformation(secondVector,targetVector,4); 52 | thirdMItarget = calcMutualInformation(thirdVector,targetVector,4); 53 | targetMItarget = calcMutualInformation(targetVector,targetVector,4); 54 | 55 | printf("MIs - first: %f, second: %f, third: %f, target %f\n",firstMItarget,secondMItarget,thirdMItarget,targetMItarget); 56 | 57 | testFirstVector = (int *) calloc(10000,sizeof(int)); 58 | testSecondVector = (int *) calloc(10000,sizeof(int)); 59 | testThirdVector = (int *) calloc(10000,sizeof(int)); 60 | testMergedVector = (int *) calloc(10000,sizeof(int)); 61 | 62 | for (i = 0; i < 10000; i++) 63 | { 64 | testFirstVector[i] = i % 2; 65 | testSecondVector[i] = i % 4; 66 | testThirdVector[i] = i % 3; 67 | } 68 | /* struct timeval 69 | * { 70 | * time_t tv_sec seconds 71 | * suseconds_t tv_usec microseconds 72 | * } 73 | */ 74 | 75 | gettimeofday(&start, NULL); 76 | for (i = 0; i < 1000; i++) 77 | { 78 | miTarget = calcMutualInformation(testFirstVector,testSecondVector,10000); 79 | entropyTarget = calcEntropy(testFirstVector,10000); 80 | cmiTarget = calcConditionalMutualInformation(testFirstVector,testSecondVector,testThirdVector,10000); 81 | mergeArrays(testFirstVector,testSecondVector,testMergedVector,10000); 82 | } 83 | gettimeofday(&end, NULL); 84 | printf("I(X;Y) = %f, H(X) = %f, I(X;Y|Z) = %f\n",miTarget,entropyTarget,cmiTarget); 85 | 86 | length = end.tv_sec - start.tv_sec; 87 | length = length + (end.tv_usec - start.tv_usec) / 1000000.0; 88 | 89 | printf("Time taken for a thousand I(X;Y), H(X), I(X;Y|Z), merge(X,Y) is %lf seconds\n",length); 90 | }/*main(int, char **)*/ 91 | -------------------------------------------------------------------------------- /MI_of_norm.m: -------------------------------------------------------------------------------- 1 | %% the simulation about the basic model of physical layer key generation scheme 2 | % calculate the mutual information between two variables x, y 3 | % r_h channel information (Guassin variables) 4 | % z1 and z1 noise signals ((Guassin variables)) 5 | % x = r_h+z1; 6 | % y = r_h+z2; 7 | 8 | % Two independent complex Gaussian random variables Z1~N(0,N1),Zb~N(0,N2), 9 | % serving as noises corrupting the channel observation by Alice and Bob, 10 | % respectively. 11 | % A complex Guassian random variables H~N(0,p) as the joint channel observation 12 | clc; 13 | clear; 14 | addpath(genpath('C:\Code file\Matlab\keygen\MIToolbox-master\matlab')); 15 | %entropy of norm h(x)=1/2*log2(2*pi*exp(1)*sigma^2) 16 | 17 | %% calculate the entropy of the norm variables with definition 18 | % signal n1 19 | sigma1 = 3; 20 | h_z1_theo= 1/2*log2(2*pi*exp(1)*sigma1^2); 21 | %calculate the entropy of variable with statistics 22 | z1 = normrnd(0,sigma1,[1 10000000])'; 23 | pre = 100; 24 | h_z1 = h(z1*pre)-log2(pre); 25 | %h_r11 = h(r1) 26 | 27 | % signal n2 28 | sigma2 = 3; 29 | h_z2_theo= 1/2*log2(2*pi*exp(1)*sigma2^2); 30 | z2 = normrnd(0,sigma2,[1 10000000])'; 31 | h_z2 = h(z2*pre)-log2(pre); 32 | 33 | % joint entropy of signal n1 and signal n2 34 | z = [z1,z2]; 35 | hj_z1z2 = h(z); 36 | 37 | %% 38 | % signal H 39 | sigma_h = 30; 40 | r_h = normrnd(0,sigma_h,[1 10000000])'; 41 | 42 | %received total signal x and y 43 | x = r_h+z1; 44 | y = r_h+z2; 45 | h_x = h(x*pre)-log2(pre); %the entropy of x 46 | h_y = h(y*pre)-log2(pre); %the entropy of y 47 | h_x_theo= 1/2*log2(2*pi*exp(1)*(sigma_h^2+sigma1^2)); %the theoretical entropy of x 48 | 49 | hj_xy =h([x,y]);% h([x*pre,y*pre])-2*log2(pre) %the joint entropy of x and y 50 | %the theoretical joint entropy of x and y 51 | hj_xy_theo = 1/2*log2((2*pi*exp(1))^2*((sigma_h^2+sigma1^2)*(sigma_h^2+sigma2^2)-sigma_h^4)); 52 | 53 | %% the mutual informatino between x and y 54 | % calculate from the I(X;Y) = h(x)+h(Y)-H(X,Y) 55 | % calculate derictly with the function 56 | % calculate with the theorectical formulation 57 | mi_cal_xy = h_x+h_y-hj_xy; 58 | mi_xy = mi(x,y); %calculate derictly from the function 59 | mi_theo = 1/2*log2(1+(sigma_h^2/(sigma1^2+sigma2^2+(sigma1^2*sigma2^2/sigma_h^2)))); 60 | 61 | 62 | -------------------------------------------------------------------------------- /OFDM-ray-exp/data_input.txt: -------------------------------------------------------------------------------- 1 | 0.0000000e+00 2 | 0.0000000e+00 3 | 0.0000000e+00 4 | 1.0000000e+00 5 | 0.0000000e+00 6 | 1.0000000e+00 7 | 0.0000000e+00 8 | 1.0000000e+00 9 | 1.0000000e+00 10 | 0.0000000e+00 11 | 0.0000000e+00 12 | 0.0000000e+00 13 | 0.0000000e+00 14 | 1.0000000e+00 15 | 1.0000000e+00 16 | 1.0000000e+00 17 | 0.0000000e+00 18 | 1.0000000e+00 19 | 1.0000000e+00 20 | 0.0000000e+00 21 | 1.0000000e+00 22 | 0.0000000e+00 23 | 0.0000000e+00 24 | 1.0000000e+00 25 | 0.0000000e+00 26 | 1.0000000e+00 27 | 0.0000000e+00 28 | 0.0000000e+00 29 | 0.0000000e+00 30 | 0.0000000e+00 31 | 1.0000000e+00 32 | 1.0000000e+00 33 | 1.0000000e+00 34 | 0.0000000e+00 35 | 1.0000000e+00 36 | 0.0000000e+00 37 | 1.0000000e+00 38 | 1.0000000e+00 39 | 1.0000000e+00 40 | 0.0000000e+00 41 | 1.0000000e+00 42 | 0.0000000e+00 43 | 0.0000000e+00 44 | 1.0000000e+00 45 | 1.0000000e+00 46 | 0.0000000e+00 47 | 1.0000000e+00 48 | 0.0000000e+00 49 | 1.0000000e+00 50 | 1.0000000e+00 51 | 1.0000000e+00 52 | 1.0000000e+00 53 | 1.0000000e+00 54 | 0.0000000e+00 55 | 0.0000000e+00 56 | 1.0000000e+00 57 | 0.0000000e+00 58 | 1.0000000e+00 59 | 0.0000000e+00 60 | 0.0000000e+00 61 | 1.0000000e+00 62 | 1.0000000e+00 63 | 1.0000000e+00 64 | 1.0000000e+00 65 | 0.0000000e+00 66 | 0.0000000e+00 67 | 0.0000000e+00 68 | 1.0000000e+00 69 | 0.0000000e+00 70 | 0.0000000e+00 71 | 1.0000000e+00 72 | 1.0000000e+00 73 | 0.0000000e+00 74 | 1.0000000e+00 75 | 1.0000000e+00 76 | 0.0000000e+00 77 | 0.0000000e+00 78 | 0.0000000e+00 79 | 0.0000000e+00 80 | 1.0000000e+00 81 | 1.0000000e+00 82 | 0.0000000e+00 83 | 0.0000000e+00 84 | 0.0000000e+00 85 | 0.0000000e+00 86 | 0.0000000e+00 87 | 1.0000000e+00 88 | 1.0000000e+00 89 | 0.0000000e+00 90 | 0.0000000e+00 91 | 1.0000000e+00 92 | 0.0000000e+00 93 | 0.0000000e+00 94 | 1.0000000e+00 95 | 0.0000000e+00 96 | 0.0000000e+00 97 | 1.0000000e+00 98 | 0.0000000e+00 99 | 0.0000000e+00 100 | 0.0000000e+00 101 | 0.0000000e+00 102 | 1.0000000e+00 103 | 1.0000000e+00 104 | 0.0000000e+00 105 | 1.0000000e+00 106 | 1.0000000e+00 107 | 1.0000000e+00 108 | 0.0000000e+00 109 | 1.0000000e+00 110 | 0.0000000e+00 111 | 0.0000000e+00 112 | 1.0000000e+00 113 | 0.0000000e+00 114 | 0.0000000e+00 115 | 0.0000000e+00 116 | 1.0000000e+00 117 | 0.0000000e+00 118 | 0.0000000e+00 119 | 0.0000000e+00 120 | 1.0000000e+00 121 | 0.0000000e+00 122 | 1.0000000e+00 123 | 0.0000000e+00 124 | 1.0000000e+00 125 | 1.0000000e+00 126 | 0.0000000e+00 127 | 0.0000000e+00 128 | 0.0000000e+00 129 | 0.0000000e+00 130 | 1.0000000e+00 131 | 0.0000000e+00 132 | 1.0000000e+00 133 | 1.0000000e+00 134 | 1.0000000e+00 135 | 0.0000000e+00 136 | 1.0000000e+00 137 | 1.0000000e+00 138 | 1.0000000e+00 139 | 1.0000000e+00 140 | 1.0000000e+00 141 | 0.0000000e+00 142 | 1.0000000e+00 143 | 1.0000000e+00 144 | 1.0000000e+00 145 | 1.0000000e+00 146 | 1.0000000e+00 147 | 0.0000000e+00 148 | 1.0000000e+00 149 | 1.0000000e+00 150 | 0.0000000e+00 151 | 1.0000000e+00 152 | 0.0000000e+00 153 | 1.0000000e+00 154 | 0.0000000e+00 155 | 1.0000000e+00 156 | 1.0000000e+00 157 | 0.0000000e+00 158 | 1.0000000e+00 159 | 0.0000000e+00 160 | 0.0000000e+00 161 | 1.0000000e+00 162 | 1.0000000e+00 163 | 0.0000000e+00 164 | 1.0000000e+00 165 | 1.0000000e+00 166 | 1.0000000e+00 167 | 1.0000000e+00 168 | 0.0000000e+00 169 | 1.0000000e+00 170 | 1.0000000e+00 171 | 1.0000000e+00 172 | 1.0000000e+00 173 | 1.0000000e+00 174 | 0.0000000e+00 175 | 1.0000000e+00 176 | 0.0000000e+00 177 | 0.0000000e+00 178 | 0.0000000e+00 179 | 1.0000000e+00 180 | 0.0000000e+00 181 | 0.0000000e+00 182 | 1.0000000e+00 183 | 0.0000000e+00 184 | 1.0000000e+00 185 | 0.0000000e+00 186 | 0.0000000e+00 187 | 0.0000000e+00 188 | 1.0000000e+00 189 | 0.0000000e+00 190 | 0.0000000e+00 191 | 1.0000000e+00 192 | 1.0000000e+00 193 | 0.0000000e+00 194 | 0.0000000e+00 195 | 1.0000000e+00 196 | 0.0000000e+00 197 | 1.0000000e+00 198 | 1.0000000e+00 199 | 1.0000000e+00 200 | 1.0000000e+00 201 | 0.0000000e+00 202 | 0.0000000e+00 203 | 0.0000000e+00 204 | 0.0000000e+00 205 | 1.0000000e+00 206 | 0.0000000e+00 207 | 1.0000000e+00 208 | 0.0000000e+00 209 | 0.0000000e+00 210 | 0.0000000e+00 211 | 1.0000000e+00 212 | 0.0000000e+00 213 | 1.0000000e+00 214 | 0.0000000e+00 215 | 0.0000000e+00 216 | 1.0000000e+00 217 | 0.0000000e+00 218 | 1.0000000e+00 219 | 0.0000000e+00 220 | 1.0000000e+00 221 | 0.0000000e+00 222 | 0.0000000e+00 223 | 0.0000000e+00 224 | 0.0000000e+00 225 | 0.0000000e+00 226 | 0.0000000e+00 227 | 1.0000000e+00 228 | 1.0000000e+00 229 | 0.0000000e+00 230 | 1.0000000e+00 231 | 0.0000000e+00 232 | 1.0000000e+00 233 | 0.0000000e+00 234 | 1.0000000e+00 235 | 0.0000000e+00 236 | 0.0000000e+00 237 | 0.0000000e+00 238 | 0.0000000e+00 239 | 1.0000000e+00 240 | 0.0000000e+00 241 | 0.0000000e+00 242 | 0.0000000e+00 243 | 0.0000000e+00 244 | 1.0000000e+00 245 | 0.0000000e+00 246 | 1.0000000e+00 247 | 1.0000000e+00 248 | 0.0000000e+00 249 | 1.0000000e+00 250 | 0.0000000e+00 251 | 1.0000000e+00 252 | 1.0000000e+00 253 | 1.0000000e+00 254 | 0.0000000e+00 255 | 0.0000000e+00 256 | 0.0000000e+00 257 | -------------------------------------------------------------------------------- /OFDM-ray-exp/mi_p.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | pn = 0.01; 4 | snr = 10:2:30; 5 | pt = 10.^(snr/10)*pn; 6 | 7 | num = length(pt); 8 | num_mc = 100000; 9 | v12 = zeros(num, num_mc); 10 | v21 = zeros(num, num_mc); 11 | x_bd1 = zeros(num, num_mc); 12 | x_bd2 = zeros(num, num_mc); 13 | 14 | for j = 1:num 15 | j 16 | for i = 1: num_mc 17 | [v12(j,i),v21(j,i),x_bd1(j,i),x_bd2(j,i)] = func_ambc_ofdm_ray_exe(pt(j)); 18 | end 19 | end 20 | corr2(v12(1,:),v21(1,:)) 21 | 22 | figure(1); 23 | plot([1:num_mc],v12(1,:)); 24 | hold on; 25 | plot([1:num_mc],v21(1,:)); 26 | 27 | mean(v12(10,:)) 28 | 29 | mean(x_bd1(4,:)) 30 | mean(x_bd2(1,:)) -------------------------------------------------------------------------------- /OFDM-ray-exp/mi_p.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangpu03/physical-key-generation/5244028d6634e612f221823e3c1b653b6df1734a/OFDM-ray-exp/mi_p.mat -------------------------------------------------------------------------------- /OFDM-ray-exp/readme.md: -------------------------------------------------------------------------------- 1 | #代码解释 2 | 3 | ## ambc_ofdm_ray_exe.m 4 | 仿真数据进行OFDM调制并进行瑞利信道传输,然后A设备进行反向散射传输,B设备接收信号,然后B设备按照论文中的设计对接收信号进行处理,得到虚拟信道信息。同样A设备也得到该虚拟信道信息。 -------------------------------------------------------------------------------- /OFDM/Picture1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangpu03/physical-key-generation/5244028d6634e612f221823e3c1b653b6df1734a/OFDM/Picture1.bmp -------------------------------------------------------------------------------- /OFDM/readme.md: -------------------------------------------------------------------------------- 1 | in this document, we simulate the OFDM communication, ambient backscatter communication between two BDs. 2 | 1. ofdm_sim 3 | the OFDM transmitting and receiving with different modulation 4 | 2. ambc_ofdm 5 | the direct transmitting with one channel over OFDM 6 | the undirect transmitting with two combination channel over OFDM 7 | discuss the multiplication of these two direct and undirect informaiton 8 | 3. ambc_ofdm_02 9 | the completely ambient backscatter communication over OFDM of the paper system model 10 | direct signal, backscatter signal, combination signals 11 | calculate the direct and backscatter signal from the combination signals. 12 | with same transmission information, the power of multiplication of two signals only consisting of CP part are the same. 13 | 4. ambc_ofdm_03 14 | based on the ambc_ofdm_02.m, we add some noise and other parameters, such as the backscatter coefficient, different path gain in different channel. -------------------------------------------------------------------------------- /entropy_of_norm.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | addpath(genpath('E:\Github\physical-key-generation\MIToolbox-master\matlab')); 4 | %calculate the entropy of norm h(x)=1/2*log2(2*pi*exp(1)*sigma^2) 5 | 6 | %% calculate the entropy of the norm variables with definition 7 | sigma1 = 3; 8 | h_norm1= 1/2*log2(2*pi*exp(1)*sigma1^2); 9 | 10 | %calculate the entropy of the norm variables with probability desity function (PDF) 11 | interval = 0.001; 12 | x = -10*sigma1:interval:10*sigma1; 13 | y = normpdf(x, 0, sigma1); 14 | h_inter = sum(y.*log2(1./y))*interval; %利用积分计算熵 15 | 16 | %calculate the entropy of variable with statistics 17 | r1 = normrnd(0,sigma1,[1 10000000])'; 18 | % figure(1); 19 | % edges = [-10*sigma:1:10*sigma]; 20 | % histogram(r1,edges); 21 | pre = 100; 22 | h_r1 = h(r1*pre)-log2(pre); 23 | 24 | %% aother Gaussian variable with variabce 3 25 | sigma2 = 3; 26 | h_norm2= 1/2*log2(2*pi*exp(1)*sigma2^2); % 标准计算熵的公式 27 | r2 = normrnd(0,sigma2,[1 10000000])'; 28 | h_r2 = h(r2*pre)-log2(pre); %利用工具函数 29 | 30 | %% joint entropy of two Gaussian variables 31 | r = [r1,r2]; 32 | h_joint = h(r); 33 | 34 | 35 | -------------------------------------------------------------------------------- /ken-gen-sim-02/c_g1_02.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | log_pt = [30,33]; 7 | Pt = 10.^(log_pt/10); %transmission power of the RF source 8 | %rho = 0.2; %power split ratio for information receiver, range is [0,1] 9 | 10 | d_f1 = 5.1; 11 | d_f2 = 6; 12 | d_h12 = 3; 13 | 14 | rho = 0:0.1:1; 15 | c_real = zeros(2,length(rho)); 16 | c_theo = zeros(2,length(rho)); 17 | e_real = zeros(2,length(rho)); 18 | e_theo = zeros(2,length(rho)); 19 | 20 | for j = 1:1:2 21 | for i = 1:length(rho) 22 | [c_real(j,i),c_theo(j,i),e_real(j,i), e_theo(j,i)] = key_gen_func_02(d_f1,d_f2,d_h12,rho(i), Pt(j)); 23 | end 24 | end 25 | 26 | G1 = zeros(2,length(rho)); 27 | G3 = zeros(2,length(rho)); 28 | G5 = zeros(2,length(rho)); 29 | % need to run it gain and plot with different SNR 30 | for j = 1:1:2 31 | for i = 1:length(rho) 32 | lambda1 = 0.7; 33 | G1(j,i) = (1-lambda1)*(c_real(j,i))/max(c_real(2,:))+lambda1*(e_real(j,i)/max(e_real(2,:))); 34 | lambda3 = 0.4; 35 | G3(j,i) = (1-lambda3)*(c_real(j,i))/max(c_real(2,:))+lambda3*(e_real(j,i)/max(e_real(2,:))); 36 | lambda5 = 0.1; 37 | G5(j,i) = (1-lambda5)*(c_real(j,i))/max(c_real(2,:))+lambda5*(e_real(j,i)/max(e_real(2,:))); 38 | end 39 | end 40 | 41 | figure(1); 42 | plot(rho,G1(1,:),'-o','DisplayName','\lambda = 0.7,SNR = 30','LineWidth',1); 43 | hold on; 44 | plot(rho,G3(1,:),'-*','DisplayName','\lambda = 0.5,SNR = 30','LineWidth',1); 45 | plot(rho,G5(1,:),'-d','DisplayName','\lambda = 0.3,SNR = 30','LineWidth',1); 46 | 47 | plot(rho,G1(2,:),'--o','DisplayName','\lambda = 0.7,SNR = 33','LineWidth',1); 48 | plot(rho,G3(2,:),'--*','DisplayName','\lambda = 0.5,SNR = 33','LineWidth',1); 49 | plot(rho,G5(2,:),'--d','DisplayName','\lambda = 0.3,SNR = 33','LineWidth',1); 50 | 51 | grid on; 52 | hold off; 53 | xlabel('\rho'); 54 | ylabel ('Objective G1'); 55 | legend; -------------------------------------------------------------------------------- /ken-gen-sim-02/c_h12_02.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | %Pt = 110; %transmission power of the RF source 7 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 8 | 9 | d_f1 = 5.1; 10 | d_f2 = 6; 11 | %d_h12 = 3; 12 | 13 | %fig.1 14 | %Pt = [100,316.2,1000,3162,10000]; 15 | log_pt = 35; 16 | Pt = 10.^(log_pt/10); 17 | d_h12 = 2:0.4:6; 18 | c_real = zeros(1,length(d_h12)); 19 | c_theo = zeros(1,length(d_h12)); 20 | e_real = zeros(1,length(d_h12)); 21 | e_theo = zeros(1,length(d_h12)); 22 | 23 | for i = 1:length(d_h12) 24 | [c_real(i),c_theo(i),e_real(i), e_theo(i)] = key_gen_func_02(d_f1,d_f2,d_h12(i),rho, Pt); 25 | end 26 | 27 | figure(1); 28 | yyaxis left 29 | plot(d_h12,c_real,'-o','DisplayName','Real MI','LineWidth',1); 30 | hold on; 31 | plot(d_h12,c_theo,'-*','DisplayName','Theo MI','LineWidth',1); 32 | %plot(Pt,c_sk); 33 | ylim([0 3.3]) 34 | yyaxis right 35 | plot(d_h12,e_real,'-->','DisplayName','Real EH','LineWidth',1); 36 | plot(d_h12,e_theo,'--<','DisplayName','Theo EH','LineWidth',1); 37 | ylim([50 155]) 38 | 39 | hold off; 40 | grid on; 41 | xlabel('the distance between two BDs'); 42 | yyaxis left 43 | ylabel ('Mutual Informaiton'); 44 | yyaxis right 45 | ylabel ('Energy harvesting'); 46 | legend; 47 | 48 | -------------------------------------------------------------------------------- /ken-gen-sim-02/c_p_02.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('E:\Github\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | %Pt = 110; %transmission power of the RF source 7 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 8 | 9 | d_f1 = 5.1; 10 | d_f2 = 6; 11 | d_h12 = 3; 12 | 13 | %fig.1 14 | %Pt = [100,316.2,1000,3162,10000]; 15 | log_pt = 25:2.5:50; 16 | Pt = 10.^(log_pt/10); 17 | c_real = zeros(1,length(Pt)); 18 | c_theo = zeros(1,length(Pt)); 19 | e_real = zeros(1,length(Pt)); 20 | e_theo = zeros(1,length(Pt)); 21 | for i = 1:length(Pt) 22 | [c_real(i),c_theo(i),e_real(i), e_theo(i)] = key_gen_func_02(d_f1,d_f2,d_h12,rho, Pt(i)); 23 | end 24 | 25 | figure(1); 26 | yyaxis left 27 | plot(log_pt,c_real,'-o','DisplayName','Real MI','LineWidth',1); 28 | hold on; 29 | plot(log_pt,c_theo,'-*','DisplayName','Theo MI','LineWidth',1); 30 | %plot(Pt,c_sk); 31 | yyaxis right 32 | plot(log_pt,e_real,'-->','DisplayName','Real EH','LineWidth',1); 33 | plot(log_pt,e_theo,'--<','DisplayName','Theo EH','LineWidth',1); 34 | %xlim([25 50]) 35 | hold off; 36 | grid on; 37 | xlabel('SNR(dB)'); 38 | yyaxis left 39 | ylabel ('Mutual Informaiton'); 40 | yyaxis right 41 | ylabel ('Energy harvesting'); 42 | legend; 43 | 44 | 45 | % figure(2); 46 | % yyaxis left 47 | % plot(Pt,c_real,'-o','DisplayName','Real MI','LineWidth',1); 48 | % hold on; 49 | % plot(Pt,c_theo,'-*','DisplayName','Theo MI','LineWidth',1); 50 | % %plot(Pt,c_sk); 51 | % yyaxis right 52 | % plot(Pt,e_real,'-->','DisplayName','Real EH','LineWidth',1); 53 | % plot(Pt,e_theo,'--<','DisplayName','Theo EH','LineWidth',1); 54 | % hold off; 55 | % grid on; 56 | % xlabel('SNR(dB)'); 57 | % yyaxis left 58 | % ylabel ('Mutual Informaiton'); 59 | % yyaxis right 60 | % ylabel ('Energy harvesting'); 61 | % 62 | % legend; 63 | -------------------------------------------------------------------------------- /ken-gen-sim-02/c_rho_02.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | log_pt = 35; 7 | Pt = 10.^(log_pt/10); %transmission power of the RF source 8 | %rho = 0.2; %power split ratio for information receiver, range is [0,1] 9 | 10 | d_f1 = 5.1; 11 | d_f2 = 6; 12 | d_h12 = 3; 13 | 14 | rho = 0:0.1:1; 15 | c_real = zeros(1,length(rho)); 16 | c_theo = zeros(1,length(rho)); 17 | e_real = zeros(1,length(rho)); 18 | e_theo = zeros(1,length(rho)); 19 | 20 | for i = 1:length(rho) 21 | [c_real(i),c_theo(i),e_real(i), e_theo(i)] = key_gen_func_02(d_f1,d_f2,d_h12,rho(i), Pt); 22 | end 23 | 24 | figure(1); 25 | yyaxis left 26 | plot(rho,c_real,'-o','DisplayName','Real MI','LineWidth',1); 27 | hold on; 28 | plot(rho,c_theo,'-*','DisplayName','Theo MI','LineWidth',1); 29 | %plot(Pt,c_sk); 30 | yyaxis right 31 | plot(rho,e_real,'-->','DisplayName','Real EH','LineWidth',1); 32 | plot(rho,e_theo,'--<','DisplayName','Theo EH','LineWidth',1); 33 | %xlim([25 50]) 34 | hold off; 35 | grid on; 36 | xlabel('rho'); 37 | yyaxis left 38 | ylabel ('Mutual Informaiton'); 39 | yyaxis right 40 | ylabel ('Energy harvesting'); 41 | legend; 42 | 43 | %% need to run it gain and plot with different SNR 44 | 45 | lambda1 = 0.7; 46 | G1 = (1-lambda1)*(c_real)/max(c_real)+lambda1*(e_real/max(e_real)); 47 | lambda3 = 0.4; 48 | G3 = (1-lambda3)*(c_real)/max(c_real)+lambda3*(e_real/max(e_real)); 49 | lambda5 = 0.1; 50 | G5 = (1-lambda5)*(c_real)/max(c_real)+lambda5*(e_real/max(e_real)); 51 | 52 | figure(2); 53 | plot(rho,G1,'-o','DisplayName','lambda = 0.7','LineWidth',1); 54 | hold on; 55 | plot(rho,G3,'-*','DisplayName','lambda = 0.5','LineWidth',1); 56 | plot(rho,G5,'-d','DisplayName','lambda = 0.3','LineWidth',1); 57 | grid on; 58 | hold off; 59 | title('Pt = 25') 60 | xlabel('rho'); 61 | ylabel ('Mutual Informaiton'); 62 | legend; -------------------------------------------------------------------------------- /ken-gen-sim-02/key_gen_func_02.m: -------------------------------------------------------------------------------- 1 | function [c_real,c_theo, e_real, e_theo] = key_gen_func_02(d_f1,d_f2,d_h12, rho, Pt) 2 | 3 | % set the parameters 4 | % channels, backscatter coefficient, energy harvesting coefficient and 5 | % the transmit power 6 | % the form of the channel model f=g*d^(L/2)--(d-distance,g-CSCG, f-channel) 7 | 8 | alpha = 0.4; %the constant of backscatter coefficient 9 | % Pt = 100; %transmission power of the RF source 10 | % rho = 0.2; %power split ratio for information receiver, range is [0,1] 11 | 12 | theta = 1; 13 | % d_f1 = 5.1; 14 | % d_f2 = 6; 15 | % d_h12 = 3; 16 | sigma_f1 = sqrt(theta*(d_f1)^(-3/2)); %channel f1 17 | f1 = normrnd(0,sigma_f1,[1 10000000])'; 18 | 19 | sigma_f2 = sqrt(theta*(d_f2)^(-3/2)); %channel f2 20 | f2 = normrnd(0,sigma_f2,[1 10000000])'; 21 | 22 | sigma_h12 = sqrt(theta*(d_h12)^(-3/2)); %channel h12 or h21 23 | h12 = normrnd(0,sigma_h12,[1 10000000])'; 24 | 25 | sigma_z1 = sqrt(1); % noise at the device BD1 26 | z1 = normrnd(0,sigma_z1,[1 10000000])'; 27 | 28 | sigma_z2 = sqrt(1); % noise at the device BD2 29 | z2 = normrnd(0,sigma_z2,[1 10000000])'; 30 | 31 | b12 = alpha*h12.*f2; 32 | b21 = alpha*h12.*f1; 33 | 34 | 35 | v1 = 4*alpha*(rho^2)*Pt*h12.*f1.*f2; 36 | v2 = 4*alpha*(rho^2)*Pt*h12.*f2.*f1; 37 | v12 = v1+z1; 38 | v21 = v2+z2; 39 | %v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 40 | %v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 41 | h(v12) 42 | h(v21) 43 | h([v12,v21]) 44 | c_theo = 1/2*log2(1+(var(v1)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(v1))))); 45 | c_real = mi(v12,v21); 46 | % 47 | % sigma_h_1e = sqrt(5.4); 48 | % h_1e = normrnd(0,sigma_h_1e,[1 1000000])'; 49 | % sigma_h_2e = sqrt(5.4); 50 | % h_2e = normrnd(0,sigma_h_2e,[1 1000000])'; 51 | % 52 | % v_e = 4*alpha^2*Pt*h_1e.*h_2e.*f1.*f2; 53 | % c_sk = cmi(v12,v21,v_e); 54 | 55 | 56 | zeta = 0.8; 57 | e_theo = 1/2*zeta*(1-rho)^2*(var(f1)+var(f2))*Pt; 58 | e_real = 1/2*zeta*(1-rho)^2*(var(b12+f1)+var(b21+f2))*Pt; -------------------------------------------------------------------------------- /ken-gen-sim-02/test_func02.m: -------------------------------------------------------------------------------- 1 | % set the parameters 2 | % channels, backscatter coefficient, energy harvesting coefficient and 3 | % the transmit power 4 | % the form of the channel model f=g*d^(L/2)--(d-distance,g-CSCG, f-channel) 5 | 6 | alpha = 0.4; %the constant of backscatter coefficient 7 | Pt = 10000; %transmission power of the RF source 8 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 9 | 10 | theta = 1; 11 | d_f1 = 5.1; 12 | d_f2 = 6; 13 | d_h12 = 3; 14 | sigma_f1 = sqrt(theta*(d_f1)^(-3/2)); %channel f1 15 | f1 = normrnd(0,sigma_f1,[1 10000000])'; 16 | 17 | sigma_f2 = sqrt(theta*(d_f2)^(-3/2)); %channel f2 18 | f2 = normrnd(0,sigma_f2,[1 10000000])'; 19 | 20 | sigma_h12 = sqrt(theta*(d_h12)^(-3/2)); %channel h12 or h21 21 | h12 = normrnd(0,sigma_h12,[1 10000000])'; 22 | 23 | sigma_z1 = sqrt(1); % noise at the device BD1 24 | z1 = normrnd(0,sigma_z1,[1 10000000])'; 25 | 26 | sigma_z2 = sqrt(1); % noise at the device BD2 27 | z2 = normrnd(0,sigma_z2,[1 10000000])'; 28 | 29 | b12 = alpha*h12.*f2; 30 | b21 = alpha*h12.*f1; 31 | 32 | 33 | v1 = 4*alpha*(rho^2)*Pt*h12.*f1.*f2; 34 | v2 = 4*alpha*(rho^2)*Pt*h12.*f2.*f1; 35 | v12 = v1+z1; 36 | v21 = v2+z2; 37 | %v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 38 | %v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 39 | h(v12) 40 | h(v21) 41 | h([v12,v21]) 42 | c_theo = 1/2*log2(1+(var(v1)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(v1))))); 43 | c_real = mi(v12,v21); 44 | % 45 | % sigma_h_1e = sqrt(5.4); 46 | % h_1e = normrnd(0,sigma_h_1e,[1 1000000])'; 47 | % sigma_h_2e = sqrt(5.4); 48 | % h_2e = normrnd(0,sigma_h_2e,[1 1000000])'; 49 | % 50 | % v_e = 4*alpha^2*Pt*h_1e.*h_2e.*f1.*f2; 51 | % c_sk = cmi(v12,v21,v_e); 52 | 53 | 54 | zeta = 0.8; 55 | e_theo = 1/2*zeta*(1-rho)^2*(var(f1)+var(f2))*Pt; 56 | e_real = 1/2*zeta*(1-rho)^2*(var(b12+f1)+var(b21+f2))*Pt; -------------------------------------------------------------------------------- /ken-gen-sim-1/c_p.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | %Pt = 110; %transmission power of the RF source 7 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 8 | 9 | %fig.1 10 | Pt = 10:20:190; 11 | c_real = zeros(1,10); 12 | c_theo = zeros(1,10); 13 | c_sk = zeros(1,10); 14 | energy = zeros(1,10); 15 | for i = 1:10 16 | [c_real(i),c_theo(i),c_sk(i), energy(i)] = key_gen_func(rho, Pt(i)); 17 | end 18 | 19 | yyaxis left 20 | plot(Pt,c_real); 21 | hold on; 22 | plot(Pt,c_theo); 23 | %plot(Pt,c_sk); 24 | yyaxis right 25 | plot(Pt,energy); 26 | hold off 27 | 28 | %[c_real,c_theo,c_sk, energy] = key_gen_func(rho, Pt) -------------------------------------------------------------------------------- /ken-gen-sim-1/c_rho.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | clc; 3 | clear; 4 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 5 | 6 | Pt = 20; %transmission power of the RF source 7 | %rho = 0.2; %power split ratio for information receiver, range is [0,1] 8 | 9 | %fig.1 10 | rho = 0:0.04:1; 11 | c_real = zeros(1,length(rho)); 12 | c_theo = zeros(1,length(rho)); 13 | c_sk = zeros(1,length(rho)); 14 | energy = zeros(1,length(rho)); 15 | for i = 1:length(rho) 16 | [c_real(i),c_theo(i),c_sk(i), energy(i)] = key_gen_func(rho(i), Pt); 17 | end 18 | 19 | figure(1); 20 | yyaxis left 21 | plot(rho,c_real,'-s'); 22 | hold on; 23 | plot(rho,c_theo,'-<'); 24 | %plot(rho,c_sk,'->'); 25 | yyaxis right 26 | plot(rho,energy,'-o'); 27 | hold off 28 | grid on; 29 | 30 | lambda1 = 1; 31 | G1 = (1-lambda1)*(c_real)/max(c_real)+lambda1*(energy/max(energy)); 32 | 33 | lambda2 = 0.6; 34 | G2 = (1-lambda2)*(c_real)/max(c_real)+lambda2*(energy/max(energy)); 35 | 36 | lambda3 = 0.5; 37 | G3 = (1-lambda3)*(c_real)/max(c_real)+lambda3*(energy/max(energy)); 38 | 39 | lambda4 = 0.4; 40 | G4 = (1-lambda4)*(c_real)/max(c_real)+lambda4*(energy/max(energy)); 41 | 42 | lambda5 = 0; 43 | G5 = (1-lambda5)*(c_real)/max(c_real)+lambda5*(energy/max(energy)); 44 | figure(2); 45 | plot(rho,G1,'-o'); 46 | hold on; 47 | plot(rho,G2,'-+'); 48 | hold on; 49 | plot(rho,G3,'-*'); 50 | plot(rho,G4,'-d'); 51 | grid on; 52 | 53 | plot(rho,G5,'-s'); 54 | hold off 55 | -------------------------------------------------------------------------------- /ken-gen-sim-1/key_gen_func.m: -------------------------------------------------------------------------------- 1 | function [c_real,c_theo,c_sk, energy] = key_gen_func(rho, Pt) 2 | 3 | % set the parameters 4 | % channels, backscatter coefficient, energy harvesting coefficient and 5 | % the transmit power 6 | % the form of the channel model f=g*d^(L/2)--(d-distance,g-CSCG, f-channel) 7 | 8 | alpha = 0.8; %the constant of backscatter coefficient 9 | %Pt = pt; %transmission power of the RF source 10 | %rho = 0.2; %power split ratio for information receiver, range is [0,1] 11 | 12 | sigma_f1 = sqrt(0.868); %channel f1 13 | f1 = normrnd(0,sigma_f1,[1 1000000])'; 14 | 15 | sigma_f2 = sqrt(0.680); %channel f2 16 | f2 = normrnd(0,sigma_f2,[1 1000000])'; 17 | 18 | sigma_h12 = sqrt(1.93); %channel h12 or h21 19 | h12 = normrnd(0,sigma_h12,[1 1000000])'; 20 | 21 | sigma_z1 = 1; % noise at the device BD1 22 | z1 = normrnd(0,sigma_z1,[1 1000000])'; 23 | 24 | sigma_z2 = 1; % noise at the device BD2 25 | z2 = normrnd(0,sigma_z2,[1 1000000])'; 26 | 27 | v1 = 4*alpha*(rho^2)*Pt*h12.*f1.*f2; 28 | v2 = 4*alpha*(rho^2)*Pt*h12.*f2.*f1; 29 | v12 = v1+z1; 30 | v21 = v2+z2; 31 | %v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 32 | %v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 33 | 34 | c_theo = 1/2*log2(1+(var(v1)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(v1))))); 35 | c_real = mi(v12,v21); 36 | 37 | sigma_h_1e = sqrt(5.4); 38 | h_1e = normrnd(0,sigma_h_1e,[1 1000000])'; 39 | sigma_h_2e = sqrt(5.4); 40 | h_2e = normrnd(0,sigma_h_2e,[1 1000000])'; 41 | 42 | v_e = 4*alpha^2*Pt*h_1e.*h_2e.*f1.*f2; 43 | c_sk = cmi(v12,v21,v_e); 44 | 45 | zeta = 0.8; 46 | energy = 1/2*zeta*(1-rho)^2*(var(f1)+var(f2))*Pt; -------------------------------------------------------------------------------- /mi_BC_system_h12_cons.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | % calculate the theortical and real mutual information between two 3 | % variables (v12,v21) from ambient backscatter system model 4 | % f1,f2: three channel variables of the corresponding channel information(Guassin variable) 5 | % h12 the channe information between two device (scale variable) 6 | % z1,z2: the noise information(Guassin variable) 7 | % v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 8 | % v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 9 | clc; 10 | clear; 11 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 12 | 13 | %% set the parameters 14 | % channels, backscatter coefficient, energy harvesting coefficient and 15 | % the transmit power 16 | % the form of the channel model f=g*d^(L/2)--(d-distance,g-CSCG, f-channel) 17 | % in this file the channel between two BDs modeled as a fat 18 | 19 | alpha = 0.8; %the constant of backscatter coefficient 20 | Pt = 100; %transmission power of the RF source 21 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 22 | 23 | sigma_f1 = sqrt(0.868); %channel f1 24 | f1 = normrnd(0,sigma_f1,[1 10000000])'; 25 | 26 | sigma_f2 = sqrt(0.680); %channel f2 27 | f2 = normrnd(0,sigma_f2,[1 10000000])'; 28 | 29 | sigma_h12 = sqrt(1.93); %channel h12 or h21 30 | h12 = sqrt(1.93) 31 | 32 | sigma_z1 = 1; % noise at the device BD1 33 | z1 = normrnd(0,sigma_z1,[1 10000000])'; 34 | 35 | sigma_z2 = 1; % noise at the device BD2 36 | z2 = normrnd(0,sigma_z2,[1 10000000])'; 37 | 38 | v1 = 4*alpha*(rho^2)*Pt*h12*f1.*f2; 39 | v2 = 4*alpha*(rho^2)*Pt*h12*f2.*f1; 40 | v12 = v1+z1; 41 | v21 = v2+z2; 42 | %v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 43 | %v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 44 | 45 | C_theo = 1/2*log2(1+(var(v1)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(v1))))); 46 | C_real = mi(v12,v21); 47 | 48 | sigma_h_1e = sqrt(5.4); 49 | h_1e = sqrt(5.4); 50 | sigma_h_2e = sqrt(5.4); 51 | h_2e = sqrt(5.4); 52 | 53 | v_e = 4*alpha^2*Pt*h_1e*h_2e*f1.*f2; 54 | c_sk = cmi(v12,v21,v_e); -------------------------------------------------------------------------------- /mi_BC_system_h12_norm.m: -------------------------------------------------------------------------------- 1 | %% simulation of the key generation between two Backscatter devices 2 | % calculate the theortical and real mutual information between two 3 | % variables (v12,v21) from ambient backscatter system model 4 | % h12,f1,f2: three channel variables of the corresponding channel information(Guassin variables) 5 | % z1,z2: the noise information(Guassin variables) 6 | % v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 7 | % v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 8 | clc; 9 | clear; 10 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 11 | 12 | %% set the parameters 13 | % channels, backscatter coefficient, energy harvesting coefficient and 14 | % the transmit power 15 | % the form of the channel model f=g*d^(L/2)--(d-distance,g-CSCG, f-channel) 16 | 17 | alpha = 0.8; %the constant of backscatter coefficient 18 | Pt = 190; %transmission power of the RF source 19 | rho = 0.2; %power split ratio for information receiver, range is [0,1] 20 | 21 | sigma_f1 = sqrt(0.868); %channel f1 22 | f1 = normrnd(0,sigma_f1,[1 100000])'; 23 | 24 | sigma_f2 = sqrt(0.680); %channel f2 25 | f2 = normrnd(0,sigma_f2,[1 100000])'; 26 | 27 | sigma_h12 = sqrt(1.93); %channel h12 or h21 28 | h12 = normrnd(0,sigma_h12,[1 100000])'; 29 | 30 | sigma_z1 = 1; % noise at the device BD1 31 | z1 = normrnd(0,sigma_z1,[1 100000])'; 32 | 33 | sigma_z2 = 1; % noise at the device BD2 34 | z2 = normrnd(0,sigma_z2,[1 100000])'; 35 | 36 | v1 = 4*alpha*(rho^2)*Pt*h12.*f1.*f2; 37 | v2 = 4*alpha*(rho^2)*Pt*h12.*f2.*f1; 38 | v12 = v1+z1; 39 | v21 = v2+z2; 40 | %v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 41 | %v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 42 | 43 | C_theo = 1/2*log2(1+(var(v1)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(v1))))); 44 | C_real = mi(v12,v21); 45 | 46 | %% the parameters of the eavesdropper 47 | % the channel information and noise 48 | sigma_h_1e = sqrt(5.4); 49 | h_1e = normrnd(0,sigma_h_1e,[1 100000])'; 50 | sigma_h_2e = sqrt(5.4); 51 | h_2e = normrnd(0,sigma_h_2e,[1 100000])'; 52 | 53 | v_e = 4*alpha^2*Pt*h_1e.*h_2e.*f1.*f2; 54 | % the conditional mutual information under the eavesdropper 55 | c_sk = cmi(v12,v21,v_e); 56 | 57 | zeta = 0.8; 58 | energy = 1/2*zeta*(1-rho)^2*(var(f1)+var(f2))*Pt; 59 | -------------------------------------------------------------------------------- /mi_variables.m: -------------------------------------------------------------------------------- 1 | %% the simulation about key generation between two backscatter devices 2 | % calculate the mutual information between two variables X, Y 3 | % f channel information (Guassin variables) 4 | % g channel information (Guassin variables) 5 | % z1 and z1 noise signals ((Guassin variables)) 6 | % X = f.*g + z1; 7 | % Y = f.*g + z2; 8 | clc; 9 | clear; 10 | addpath(genpath('C:\Code file\Matlab\physical-key-generation\MIToolbox-master\matlab')); 11 | 12 | sigma_f = 7; 13 | f = normrnd(0,sigma_f,[1 100000000])'; 14 | 15 | sigma_g = 6; 16 | g = normrnd(0,sigma_g,[1 100000000])'; 17 | 18 | sigma_z1 = 1; 19 | z1 = normrnd(0,sigma_z1,[1 100000000])'; 20 | 21 | sigma_z2 = 1; 22 | z2 = normrnd(0,sigma_z2,[1 100000000])'; 23 | 24 | sigma_z3 = 1; 25 | z2 = normrnd(0,sigma_z2,[1 100000000])'; 26 | 27 | X = f.*g + z1; 28 | Y = f.*g + z2; 29 | 30 | pre = 100; 31 | h_x = h(X*pre)-log2(pre); 32 | h_theo_x = 1/2*log2(2*pi*exp(1)*((sigma_f^2*sigma_g^2)+sigma_z1^2)); 33 | h_y = h(Y*pre)-log2(pre); 34 | h_joint_xy = h([X,Y]); 35 | 36 | mi_theo= 1/2*log2(1+(var(f.*g)/(var(z1)+var(z2)+(var(z1)*var(z2)/var(f.*g))))); 37 | 38 | mi_xy = mi(X,Y); 39 | 40 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | this document is used to discuss the mutual information between two variables 2 | 3 | # 1. mi_variables 4 | % calculate the mutual information between two variables X, Y, that multiply from two Guassian variables 5 | % f channel information (Guassin variables) 6 | % g channel information (Guassin variables) 7 | % z1 and z1 noise signals ((Guassin variables)) 8 | % X = f.*g + z1; 9 | % Y = f.*g + z2; 10 | 11 | # 2. mi_of_norm 12 | % calculate the mutual information between two Guassin variables x, y 13 | % r_h channel information (Guassin variables) 14 | % z1 and z1 noise signals ((Guassin variables)) 15 | % x = r_h+z1; 16 | % y = r_h+z2; 17 | 18 | # 3. entropy_of_norm 19 | % calculate the entropy of the norm variable with different manners. 20 | 21 | # mi_BC_system_h12_norm.m 22 | % based on the direct channel model to calculate the mutual information between two backscatter devices 23 | % calculate the theortical and real mutual information between two 24 | % variables (v12,v21) from ambient backscatter system model 25 | % h12,f1,f2: three channel variables of the corresponding channel information(Guassin variables) 26 | % z1,z2: the noise information(Guassin variables) 27 | % v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 28 | % v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 29 | 30 | # mi_BC_system_h12_cons.m 31 | % calculate the theortical and real mutual information between two 32 | % variables (v12,v21) from ambient backscatter system model 33 | % f1,f2: three channel variables of the corresponding channel information(Guassin variable) 34 | % h12 the channe information between two device (scale variable) 35 | % z1,z2: the noise information(Guassin variable) 36 | % v12 = 4*alpha*(rho^2)*Pt*h12*f1.*f2+z1; 37 | % v21 = 4*alpha*(rho^2)*Pt*h12*f2.*f1+z2; 38 | 39 | # key-gen-sim-01 and key-gen-sim-02 40 | % simulate the key generation scheme with the based channel model that are modeled as a Gaussian variables. These two documents are mainly used to verify the idea and mutual information between two devices. 41 | 42 | 43 | -------------------------------------------------------------------------------- /sim07/ambc_ofdm.m: -------------------------------------------------------------------------------- 1 | % consists of all precedures of the OFDM 2 | % 3 | clear; 4 | clc; 5 | 6 | %% simulation parameters 7 | d = [8, 7, 3]; 8 | taps = [8, 7, 3]; 9 | n_L = max(taps(1),taps(2))+taps(3)-1; 10 | 11 | h1 = ray_model(d(1),taps(1)); 12 | h2 = ray_model(d(2),taps(2)); 13 | 14 | h_12 = ray_model(d(3),taps(3)); 15 | 16 | cor_h1_he = 0; 17 | cor_h12_he1 = 0; 18 | 19 | he = eave_ray_model(h1,0,d(1)); 20 | h_e1 = eave_ray_model(h_12,0,d(3)); 21 | 22 | 23 | n_fft = 128; % IFFT/FFT size 24 | n_cp = n_fft/4; % size of cyclic prefix extension 25 | n_frame = 1; % the acount of the OFDM frame 26 | n_ofdm = n_fft + n_cp; 27 | 28 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 29 | mod_method = 'QPSK'; 30 | % calculate modulation order from modulation method 31 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 32 | mod_order = find(ismember(mod_methods, mod_method)); 33 | % generate the data 34 | rand_ints_gen = randi(2,n_fft*mod_order*n_frame,1)-1; 35 | save data_input.txt -ascii rand_ints_gen 36 | rand_ints = load("data_input.txt"); 37 | 38 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, 0); 39 | data_cp_pwr = mean(abs(data_ofdm).^2) 40 | 41 | 42 | 43 | pt = 1; 44 | snr = 15; 45 | alpha = 0.3 + 1i*0.4; 46 | pw_noise = pt/10^(snr/10); 47 | 48 | % all transmissions in ambient backscatter communication 49 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 50 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 51 | 52 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 53 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 54 | 55 | y1_b = ofdm_trans(back2, h_12, pw_noise); 56 | y2_b = ofdm_trans(back1, h_12, pw_noise); 57 | 58 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 59 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 60 | 61 | v_y1_cp = mean(abs(y1_cp)); 62 | v_y2_cp = mean(abs(y2_cp)); 63 | 64 | 65 | -------------------------------------------------------------------------------- /sim07/ambc_ofdm_eve.m: -------------------------------------------------------------------------------- 1 | % consists of all precedures of the OFDM 2 | % 3 | clear; 4 | clc; 5 | 6 | % simulation parameters 7 | 8 | n_fft = 128; % IFFT/FFT size 9 | n_cp = n_fft/4; % size of cyclic prefix extension 10 | n_frame = 1; % the acount of the OFDM frame 11 | n_ofdm = n_fft + n_cp; 12 | 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | 20 | h_12 = ray_model(d(3),taps(3)); 21 | h_21 = h_12; 22 | 23 | cor_h1_he = 1; 24 | cor_h12_he2 = 1; 25 | 26 | % assume Eve locate closer to device 1 27 | cor = 0; 28 | he = eave_ray_model(h1,cor_h1_he,d(1)); 29 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 30 | 31 | d_e1 = 1; 32 | tap_e1 = 1; 33 | h_e1 = ray_model(d_e1,tap_e1); 34 | 35 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 36 | mod_method = 'QPSK'; 37 | % calculate modulation order from modulation method 38 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 39 | mod_order = find(ismember(mod_methods, mod_method)); 40 | % generate the data 41 | rand_ints_gen = randi(2,n_fft*mod_order*n_frame,1)-1; 42 | save data_input.txt -ascii rand_ints_gen 43 | rand_ints = load("data_input.txt"); 44 | 45 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, 0); 46 | 47 | pt = 1; 48 | snr = 40; 49 | alpha = 0.3 + 1i*0.4; 50 | pw_noise = pt/10^(snr/10); 51 | 52 | % all transmissions in ambient backscatter communication 53 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 54 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 55 | 56 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 57 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 58 | 59 | y1_b = ofdm_trans(back2, h_12, pw_noise); 60 | y2_b = ofdm_trans(back1, h_12, pw_noise); 61 | 62 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 63 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 64 | 65 | v_y1_cp = mean(abs(y1_cp)); 66 | v_y2_cp = mean(abs(y2_cp)); 67 | 68 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 69 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 70 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 71 | 72 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 73 | v_ye1_cp = mean(abs(ye1_cp)); 74 | v_ye2_cp = mean(abs(ye2_cp)); -------------------------------------------------------------------------------- /sim07/eave_ray_model.m: -------------------------------------------------------------------------------- 1 | function h = eave_ray_model(h_b,cor,d) 2 | % generate a exponential rayleigh model that is correlated to other 3 | % Raymodel 4 | % inputs: 5 | % d: the distance between two objects 6 | % cor: correlation coefficient 7 | % h_b: the base Rayleigh channel model 8 | % output: 9 | % h: the exponential Rayleigh model correlated to channel h 10 | lamda = 3; 11 | 12 | h_cg = d^(-lamda/2); 13 | 14 | pow_h = exp(-(0:length(h_b)-1)); 15 | pow_h = h_cg*pow_h/norm(pow_h); 16 | 17 | h = cor*h_b + sqrt(1-cor^2).*sqrt(pow_h).* (randn(1,length(h_b)) + 1i*randn(1,length(h_b))); 18 | -------------------------------------------------------------------------------- /sim07/evea_design.m: -------------------------------------------------------------------------------- 1 | function [ye1_cp, ye2_cp] = evea_design(y_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L) 2 | % 3 | 4 | sym_rem = mod(n_ofdm-mod(length(y_d),n_ofdm),n_ofdm); 5 | padding = repmat(0+0i,sym_rem,1); 6 | y_d_padded = [y_d;padding]; 7 | 8 | sym_rem = mod(n_ofdm-mod(length(y_b_e1),n_ofdm),n_ofdm); 9 | padding = repmat(0+0i,sym_rem,1); 10 | y_b_e1_padded = [y_b_e1;padding]; 11 | 12 | sym_rem = mod(n_ofdm-mod(length(y_b_e2),n_ofdm),n_ofdm); 13 | padding = repmat(0+0i,sym_rem,1); 14 | y_b_e2_padded = [y_b_e2;padding]; 15 | 16 | y_e2 = y_d_padded+y_b_e2_padded; 17 | 18 | y_e1 = y_d_padded+y_b_e1_padded; 19 | % calculate the desired information at receivering devices 20 | n_fft = n_ofdm - n_cp; 21 | zb_e2 = y_e2(n_L:n_cp) - y_e2(n_fft+n_L:n_fft+n_cp); 22 | for n = 1:1:n_frame-1 23 | zb_e2 =[zb_e2(:); (y_e2(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y_e2(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 24 | end 25 | 26 | zd_e2 = y_e2(n_L:n_cp) + y_e2(n_fft+n_L:n_fft+n_cp); 27 | for n = 1:1:n_frame-1 28 | zd_e2 =[zd_e2(:); (y_e2(n*n_ofdm+n_L:n*n_ofdm+n_cp)+y_e2(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 29 | end 30 | ye2_cp = zb_e2 .* zd_e2; %%发射信号和直射信号相乘,得到第一类窃听方法 31 | 32 | n_fft = n_ofdm - n_cp; 33 | zb_e1 = y_e1(n_L:n_cp) - y_e1(n_fft+n_L:n_fft+n_cp); 34 | for n = 1:1:n_frame-1 35 | zb_e1 =[zb_e1(:); (y_e1(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y_e1(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 36 | end 37 | 38 | ye1_cp = zb_e1 .* zb_e2; %%两个反射信号相乘,得到第二类窃听方法 39 | -------------------------------------------------------------------------------- /sim07/mi_dist.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = mi_dist(data_ofdm, n_ofdm, n_cp ,n_frame, d, taps, snr) 2 | pt = 1; 3 | %snr = 100; 4 | alpha = 0.3 + 1i*0.4; 5 | pw_noise = pt/10^(snr/10); 6 | 7 | n_L = max(taps(1),taps(2))+taps(3)-1; 8 | 9 | h1 = ray_model(d(1),taps(1)); 10 | h2 = ray_model(d(2),taps(2)); 11 | 12 | h_12 = ray_model(d(3),taps(3)); 13 | h_21 = h_12; 14 | 15 | cor = 0; 16 | cor_h1_he = cor; 17 | cor_h12_he2 = cor; 18 | 19 | % assume Eve locate closer to device 1 20 | %cor = 0; 21 | he = eave_ray_model(h1,cor_h1_he,d(1)); 22 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 23 | 24 | d_e1 = 1; 25 | tap_e1 = 1; 26 | h_e1 = ray_model(d_e1,tap_e1); 27 | 28 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 29 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 30 | 31 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 32 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 33 | 34 | y1_b = ofdm_trans(back2, h_12, pw_noise); 35 | y2_b = ofdm_trans(back1, h_12, pw_noise); 36 | 37 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 38 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 39 | 40 | v_y1_cp = mean(abs(y1_cp)); 41 | v_y2_cp = mean(abs(y2_cp)); 42 | 43 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 44 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 45 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 46 | 47 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 48 | v_ye1_cp = mean(abs(ye1_cp)); 49 | v_ye2_cp = mean(abs(ye2_cp)); -------------------------------------------------------------------------------- /sim07/mi_snr.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr(data_ofdm, n_ofdm, n_cp ,n_frame, snr) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | h_12 = ray_model(d(3),taps(3)); 20 | 21 | pt = 1; 22 | %snr = 100; 23 | alpha = 0.3 + 1i*0.4; 24 | pw_noise = pt/10^(snr/10); 25 | 26 | % all transmissions in ambient backscatter communication 27 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 28 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 29 | 30 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 31 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 32 | 33 | y1_b = ofdm_trans(back2, h_12, pw_noise); 34 | y2_b = ofdm_trans(back1, h_12, pw_noise); 35 | 36 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 37 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 38 | 39 | v_y1_cp = mean(abs(y1_cp)); 40 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim07/ofdm_back.m: -------------------------------------------------------------------------------- 1 | function back_data = ofdm_back(data, alpha, n_ofdm, n_frame) 2 | % inputs: 3 | % data: the ofdm data before backscatter 4 | % alpha: backscatter coefficient 5 | % n_ofdm: the number of IFFT of a ofdm frame 6 | % n_frame: the number of frame of the all data 7 | % outputs: 8 | % back_data: the ofdm data after backscatter 9 | 10 | 11 | % the designing of the backscatter waveform at the user 1 12 | bc_signal_fh = ones(n_ofdm/2,1); 13 | bc_signal_bh = ones(n_ofdm/2,1)-2; 14 | bc_signal = [bc_signal_fh; bc_signal_bh]; 15 | bc_signal = repmat(bc_signal,n_frame,1); 16 | 17 | % backscatter operation of the signal from user1 18 | sym_rem = mod(length(data),n_ofdm); 19 | padding_bc = zeros(sym_rem,1); %pad zero 20 | bc_signal = [bc_signal;padding_bc]; 21 | %size(bc_signal) 22 | %size(data) 23 | back_data = alpha*bc_signal.*data; 24 | -------------------------------------------------------------------------------- /sim07/ofdm_module.m: -------------------------------------------------------------------------------- 1 | function ofdm_data = ofdm_module(data,mod_method, n_fft, n_cp, cp_flag) 2 | % modulate the data with OFDM 3 | % inputs: 4 | % data: input raw data with bits, length = n_fft*mod_order*n_frame 5 | % mod_method: symbol modulation 6 | % n_fft: IFFT/FFT size 7 | % n_cp: size of cyclic prefix extension 8 | % n_frame: the acount of the OFDM frame 9 | % cp_flag: 1--cp, 0--guard 10 | %output: 11 | % ofdm_data: modulated OFDM data 12 | 13 | if nargin < 4 14 | cp_flag = 1; 15 | end 16 | 17 | %n_ofdm = n_fft+n_cp; 18 | % calculate modulation order from modulation method 19 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 20 | mod_order = find(ismember(mod_methods, mod_method)); 21 | 22 | % input data to binary stream 23 | rand_bits = dec2bin(data(:)); 24 | 25 | % binary stream to symbols 26 | % Parse binary stream into mod_order bit symbols 27 | % pads input signal to appropriate length 28 | sym_rem = mod(mod_order-mod(length(rand_bits),mod_order),mod_order); 29 | padding = repmat('0',sym_rem,1); 30 | rand_bits_padded = [rand_bits;padding]; 31 | cons_data = reshape(rand_bits_padded, mod_order,length(rand_bits_padded)/mod_order)'; 32 | cons_sym_id = bin2dec(cons_data); 33 | 34 | % symbol modulation codebook 35 | % BPSK 36 | if mod_order == 1 37 | mod_ind = 2^(mod_order-1); 38 | n = 0:pi/mod_ind:2*pi-pi/mod_ind; 39 | in_phase = cos(n); 40 | quadrature = sin(n); 41 | symbol_book = (in_phase+quadrature*1i)'; 42 | end 43 | 44 | % phase shift keying about unit circle 45 | if mod_order == 2 || mod_order ==3 46 | mod_ind = 2^(mod_order-1); 47 | n = 0:pi/mod_ind:2*pi-pi/mod_ind; 48 | in_phase = cos(n+pi/4); 49 | quadrature = sin(n+pi/4); 50 | symbol_book = (in_phase+quadrature*1i)'; 51 | end 52 | 53 | % 16QAM, 64QAM modulaiton 54 | if mod_order ==4 || mod_order ==6 55 | mod_ind = 2^(mod_order-2); 56 | in_phase = repmat(linspace(-1,1,mod_ind),mod_ind,1); 57 | quadrature = repmat(linspace(-1,1,mod_ind)',1,mod_ind); 58 | symbol_book = in_phase(:)+quadrature(:)*1i; 59 | end 60 | 61 | % 32 QAM modulation 62 | % generate 6x6 constellation and removes corners 63 | if mod_order ==5 64 | mod_ind = 6; 65 | in_phase = repmat(linspace(-1,1,mod_ind),mod_ind,1); 66 | quadrature = repmat(linspace(-1,1,mod_ind)',1,mod_ind); 67 | symbol_book = in_phase(:)+quadrature(:)*1i; 68 | symbol_book = symbol_book([2:5 7:30 32:35]); 69 | end 70 | 71 | % modulate data according to symbol_book 72 | X = symbol_book(cons_sym_id+1); 73 | %size_X = size(X) 74 | 75 | % use IFFT to move to time domain 76 | % pad input signal to appropriate lengthmod(length(X),n_fft) 77 | fft_rem = mod(n_fft-mod(length(X),n_fft),n_fft); 78 | X_padded = [X;zeros(fft_rem,1)]; 79 | X_blocks = reshape(X_padded, n_fft,length(X_padded)/n_fft); 80 | x = ifft(X_blocks); 81 | %data_x_pwr = mean(abs(x).^2) 82 | % add cyclic prefix extension and shift from parallel to serial 83 | guard = sqrt(mean(abs(x).^2))/sqrt(2)*(1+1i); 84 | guard = repmat(guard,n_cp,1); 85 | 86 | if cp_flag 87 | x_cp = [x(end-n_cp+1:end,:);x]; 88 | else 89 | x_cp = [guard;x(1:n_fft-n_cp,:);guard]; 90 | end 91 | 92 | ofdm_data = x_cp(:); 93 | 94 | ofdm_data = ofdm_data/sqrt(mean(abs(ofdm_data).^2)); 95 | 96 | 97 | -------------------------------------------------------------------------------- /sim07/ofdm_trans.m: -------------------------------------------------------------------------------- 1 | function channel_data = ofdm_trans(ofdm_data, h, noise_pw) 2 | % inputs: 3 | % ofdm_data: modulated data for transmitting 4 | % h: the Rayleigh channel that data will go through 5 | % noise_pw: the noise power recieved at receiver 6 | % output: 7 | % channel data: the received data at receiver, including data signal and 8 | % noise signal 9 | 10 | channel_data = conv(ofdm_data,h); 11 | 12 | 13 | noise = normrnd(0,sqrt(noise_pw),size(channel_data))+normrnd(0,sqrt(noise_pw),size(channel_data))*1i; 14 | channel_data = channel_data+noise; -------------------------------------------------------------------------------- /sim07/plot_mi_dist.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | 4 | addpath('E:\Github\physical-key-generation\MIToolbox-master\matlab'); 5 | 6 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 7 | mod_method = 'QPSK'; 8 | % calculate modulation order from modulation method 9 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 10 | mod_order = find(ismember(mod_methods, mod_method)); 11 | 12 | % 13 | % nfft = 256, K =1 14 | n_fft = 256; 15 | n_cp = n_fft/4; % size of cyclic prefix extension 16 | n_ofdm = n_fft + n_cp; 17 | K = 1; 18 | c_flag = 1; 19 | % generate the data 20 | rand_ints_gen = randi(2,n_fft*mod_order*K,1)-1; 21 | save data_input.txt -ascii rand_ints_gen 22 | rand_ints = load("data_input.txt"); 23 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, c_flag); 24 | num_sim = 50000; 25 | snr = 10:3:40; 26 | v1 = zeros(num_sim, length(snr)); 27 | v2 = zeros(num_sim, length(snr)); 28 | ve1 = zeros(num_sim, length(snr)); 29 | ve2 = zeros(num_sim, length(snr)); 30 | 31 | %% 32 | d = [8 7 3]; 33 | taps = [8 7 3]; 34 | for i = 1:length(snr) 35 | for j = 1:num_sim 36 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 37 | end 38 | end 39 | 40 | mean_v1 = repmat(mean(v1), num_sim,1); 41 | mean_v2 = repmat(mean(v2), num_sim,1); 42 | mean_ve1 = repmat(mean(ve1), num_sim,1); 43 | mean_ve2 = repmat(mean(ve2), num_sim,1); 44 | 45 | v1_bit = double(v1>= mean_v1); 46 | v2_bit = double(v2>= mean_v2); 47 | ve1_bit = double(ve1>= mean_ve1); 48 | ve2_bit = double(ve2>= mean_ve2); 49 | 50 | cmi_ve2 = zeros(1,length(snr)); 51 | cmi_ve1 = zeros(1,length(snr)); 52 | mi_bit = zeros(1,length(snr)); 53 | for i = 1:length(snr) 54 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 55 | end 56 | 57 | for i = 1:length(snr) 58 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 59 | end 60 | 61 | for i = 1:length(snr) 62 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 63 | end 64 | 65 | v1_873 = v1; 66 | v2_873 = v2; 67 | ve1_873 = ve1; 68 | ve2_873 = ve2; 69 | mi_bit_873 = mi_bit; 70 | cmi_ve2_873 = cmi_ve2; 71 | cmi_ve1_873 = cmi_ve1; 72 | 73 | %% 74 | d = [12 7 3]; 75 | taps = [12 7 3]; 76 | for i = 1:length(snr) 77 | for j = 1:num_sim 78 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 79 | end 80 | end 81 | mean_v1 = repmat(mean(v1), num_sim,1); 82 | mean_v2 = repmat(mean(v2), num_sim,1); 83 | mean_ve1 = repmat(mean(ve1), num_sim,1); 84 | mean_ve2 = repmat(mean(ve2), num_sim,1); 85 | 86 | v1_bit = double(v1>= mean_v1); 87 | v2_bit = double(v2>= mean_v2); 88 | ve1_bit = double(ve1>= mean_ve1); 89 | ve2_bit = double(ve2>= mean_ve2); 90 | 91 | cmi_ve2 = zeros(1,length(snr)); 92 | cmi_ve1 = zeros(1,length(snr)); 93 | mi_bit = zeros(1,length(snr)); 94 | for i = 1:length(snr) 95 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 96 | end 97 | 98 | for i = 1:length(snr) 99 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 100 | end 101 | 102 | for i = 1:length(snr) 103 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 104 | end 105 | 106 | v1_1273 = v1; 107 | v2_1273 = v2; 108 | ve1_1273 = ve1; 109 | ve2_1273 = ve2; 110 | mi_bit_1273 = mi_bit; 111 | cmi_ve2_1273 = cmi_ve2; 112 | cmi_ve1_1273 = cmi_ve1; 113 | 114 | 115 | %% 116 | d = [12 7 6]; 117 | taps = [12 7 6]; 118 | for i = 1:length(snr) 119 | for j = 1:num_sim 120 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 121 | end 122 | end 123 | 124 | mean_v1 = repmat(mean(v1), num_sim,1); 125 | mean_v2 = repmat(mean(v2), num_sim,1); 126 | mean_ve1 = repmat(mean(ve1), num_sim,1); 127 | mean_ve2 = repmat(mean(ve2), num_sim,1); 128 | 129 | v1_bit = double(v1>= mean_v1); 130 | v2_bit = double(v2>= mean_v2); 131 | ve1_bit = double(ve1>= mean_ve1); 132 | ve2_bit = double(ve2>= mean_ve2); 133 | 134 | cmi_ve2 = zeros(1,length(snr)); 135 | cmi_ve1 = zeros(1,length(snr)); 136 | mi_bit = zeros(1,length(snr)); 137 | for i = 1:length(snr) 138 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 139 | end 140 | 141 | for i = 1:length(snr) 142 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 143 | end 144 | 145 | for i = 1:length(snr) 146 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 147 | end 148 | 149 | v1_1276 = v1; 150 | v2_1276 = v2; 151 | ve1_1276 = ve1; 152 | ve2_1276 = ve2; 153 | mi_bit_1276 = mi_bit; 154 | cmi_ve2_1276 = cmi_ve2; 155 | cmi_ve1_1276 = cmi_ve1; 156 | 157 | plot(snr, mi_bit_873,'r-o','LineWidth',1.5); 158 | hold on; 159 | plot(snr, mi_bit_1273,'k-x','LineWidth',1.5); 160 | plot(snr, mi_bit_1276,'b-*','LineWidth',1.5); 161 | plot(snr, cmi_ve2_873,'r--s','LineWidth',1.5); 162 | plot(snr, cmi_ve2_1273,'k--^','LineWidth',1.5); 163 | plot(snr, cmi_ve2_1276,'b--v','LineWidth',1.5); 164 | plot(snr, mi_bit_873-cmi_ve2_873,'r-.v','LineWidth',1.5); 165 | plot(snr, mi_bit_1273-cmi_ve2_1273,'k-.s','LineWidth',1.5); 166 | plot(snr, mi_bit_1276-cmi_ve2_1276,'b-.d','LineWidth',1.5); 167 | hold off; 168 | grid on; 169 | 170 | axis([10 40 0 1.1]) 171 | txt = {'Red: d_1 = 8, d_2 = 7, d_{12} = 3 ','Black: d_1 = 12, d_2 = 7, d_{12} = 3','Blue: d_1 = 12, d_2 = 7, d_{12} = 6'}; 172 | annotation('textbox',[0.15,0.74,0.35,0.165],'LineStyle','-','LineWidth',1,'String',txt) 173 | 174 | elps1 = annotation('ellipse',[0.800 0.715 0.0500 0.0500]); 175 | elps1.LineWidth = 1.5; 176 | elps1.Color = '#D95319'; 177 | 178 | x = [0.770,0.820]; 179 | y = [0.57,0.715]; 180 | a1 = annotation('textarrow',x, y,'String','Secret key rate'); 181 | a1.Color = 'red'; 182 | a1.FontSize = 12; 183 | a1.LineWidth = 1.5; 184 | 185 | elps2 = annotation('ellipse',[0.6500 0.75 0.0500 0.0500]); 186 | elps2.LineWidth = 1.5; 187 | elps2.Color = '#D95319'; 188 | 189 | x2 = [0.65,0.6700]; 190 | y2 = [0.65,0.75]; 191 | a2 = annotation('textarrow',x2, y2,'String','Mutual information'); 192 | a2.Color = 'red'; 193 | a2.FontSize = 12; 194 | a2.LineWidth = 1.5; 195 | 196 | elps3 = annotation('ellipse',[0.800 0.117 0.0500 0.0500]); 197 | elps3.LineWidth = 1.5; 198 | elps3.Color = '#D95319'; 199 | x3 = [0.77,0.830]; 200 | y3 = [0.25,0.17]; 201 | a3 = annotation('textarrow',x3, y3,'String','Leak information'); 202 | a3.Color = 'red'; 203 | a3.FontSize = 12; 204 | a3.LineWidth = 1.5; 205 | %ylabel('Information (bit)'); 206 | xlabel('SNR (dB)'); 207 | 208 | -------------------------------------------------------------------------------- /sim07/plot_mi_eth.m: -------------------------------------------------------------------------------- 1 | % plot_mi_eth.m 2 | 3 | clc; 4 | clear; 5 | 6 | d = [10 7 3]; 7 | alpha = 0.3 + 1i*0.4; 8 | 9 | lamda = 3; 10 | h = 5*d.^(-lamda/2); 11 | 12 | rho1 =0:0.01:1; 13 | rho2 =0:0.01:1; 14 | 15 | %% 16 | snr = 30; 17 | pt = 1; 18 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 19 | pw_noise = pt/10^(snr/10); 20 | 21 | E_th = 0:0.001:0.1; 22 | mi_max = zeros(1,length(E_th)); 23 | mi_diag_max = zeros(1,length(E_th)); 24 | for j = 1:length(E_th) 25 | mi = zeros(length(rho1),length(rho2)); 26 | for i = 1:length(rho1) 27 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 28 | if E1 < E_th(j) 29 | break; 30 | end 31 | end 32 | num_rho1 = i-1; 33 | 34 | for i = 1:length(rho2) 35 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 36 | if E2 < E_th(j) 37 | break; 38 | end 39 | end 40 | num_rho2 = i-1; 41 | 42 | for i = 1:num_rho1 43 | for k = 1:num_rho2 44 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 45 | end 46 | end 47 | 48 | mi_max (j) = max(max(mi)'); 49 | mi_diag_max(j) = max(diag(mi)); 50 | end 51 | 52 | 53 | %% 54 | snr = 25; 55 | pt = 1; 56 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 57 | pw_noise = pt/10^(snr/10); 58 | 59 | E_th = 0:0.001:0.1; 60 | mi_25_max = zeros(1,length(E_th)); 61 | mi_diag_25_max = zeros(1,length(E_th)); 62 | for j = 1:length(E_th) 63 | mi = zeros(length(rho1),length(rho2)); 64 | for i = 1:length(rho1) 65 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 66 | if E1 < E_th(j) 67 | break; 68 | end 69 | end 70 | num_rho1 = i-1; 71 | 72 | for i = 1:length(rho2) 73 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 74 | if E2 < E_th(j) 75 | break; 76 | end 77 | end 78 | num_rho2 = i-1; 79 | 80 | for i = 1:num_rho1 81 | for k = 1:num_rho2 82 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 83 | end 84 | end 85 | 86 | mi_25_max (j) = max(max(mi)'); 87 | %mi_diag_35_max(j) = max(diag(mi)); 88 | end 89 | 90 | %% 91 | snr = 30; 92 | pt = 1.5; 93 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 94 | pw_noise = 1/10^(snr/10); 95 | 96 | E_th = 0:0.001:0.1; 97 | mi_2_max = zeros(1,length(E_th)); 98 | mi_diag_2_max = zeros(1,length(E_th)); 99 | for j = 1:length(E_th) 100 | mi = zeros(length(rho1),length(rho2)); 101 | for i = 1:length(rho1) 102 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 103 | if E1 < E_th(j) 104 | break; 105 | end 106 | end 107 | num_rho1 = i-1; 108 | 109 | for i = 1:length(rho2) 110 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 111 | if E2 < E_th(j) 112 | break; 113 | end 114 | end 115 | num_rho2 = i-1; 116 | 117 | for i = 1:num_rho1 118 | for k = 1:num_rho2 119 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 120 | end 121 | end 122 | 123 | mi_2_max (j) = max(max(mi)'); 124 | %mi_diag_35_max(j) = max(diag(mi)); 125 | end 126 | 127 | num_max = sum(mi_max ~= 0); 128 | num_diag_max = sum(mi_diag_max ~= 0); 129 | num_25_max = sum(mi_25_max ~= 0); 130 | num_2_max = sum(mi_2_max ~= 0); 131 | % 132 | plot([E_th(1:num_max),E_th(num_max)], [mi_max(1:num_max),0],'r-*','LineWidth',1); 133 | hold on; 134 | plot(E_th(1:num_diag_max), mi_diag_max(1:num_diag_max),'b-s','LineWidth',1); 135 | hold on; 136 | plot(E_th(1:num_25_max), mi_25_max(1:num_25_max),'k-v','LineWidth',1); 137 | hold on; 138 | plot([E_th(1:num_2_max),E_th(num_2_max)], [mi_2_max(1:num_2_max),0],'k-o','LineWidth',1); 139 | hold on; 140 | % % plot(E_th, mi_diag_max_2,'LineWidth',1.5); 141 | 142 | area1 = area([0,E_th(4)],[mi_max(4),mi_max(4)], 'LineStyle','none'); 143 | plot([0,E_th(4)],[mi_max(4),mi_max(4)],'LineStyle','--','LineWidth',1.5,'Color','#0072BD'); 144 | plot([E_th(4),E_th(4)],[0,mi_max(4)],'LineStyle','--','LineWidth',1.5,'Color','#0072BD'); 145 | 146 | area2 = area([0,E_th(9)],[mi_max(9),mi_max(9)], 'LineStyle','none'); 147 | plot([0,E_th(9)],[mi_max(9),mi_max(9)],'LineStyle','--','LineWidth',1.5,'Color','#77AC30'); 148 | plot([E_th(9),E_th(9)],[0,mi_max(9)],'LineStyle','--','LineWidth',1.5,'Color','#77AC30'); 149 | 150 | area3 = area([0,E_th(12)],[mi_max(12),mi_max(12)], 'LineStyle','none'); 151 | plot([0,E_th(12)],[mi_max(12),mi_max(12)],'LineStyle','--','LineWidth',1.5,'Color','#A2142F'); 152 | plot([E_th(12),E_th(12)],[0,mi_max(12)],'LineStyle','--','LineWidth',1.5,'Color','#A2142F'); 153 | 154 | area1.FaceColor = '#0072BD'; 155 | area2.FaceColor = '#77AC30'; 156 | area3.FaceColor = '#A2142F'; 157 | area1.FaceAlpha = 0.1; 158 | area2.FaceAlpha = 0.1; 159 | area3.FaceAlpha = 0.1; 160 | grid on; 161 | 162 | dim = [0.003/0.0127 0.725/1.05 0.0500 0.0500]; 163 | a1 = annotation('textbox',dim,'String','K1'); 164 | a1.Color = 'red'; 165 | a1.FontSize = 12; 166 | a1.LineStyle = 'none'; 167 | 168 | dim = [0.003/0.0068 0.725/1.476 0.0500 0.0500]; 169 | a2 = annotation('textbox',dim,'String','K2'); 170 | a2.Color = 'red'; 171 | a2.FontSize = 12; 172 | a2.LineStyle = 'none'; 173 | 174 | dim = [0.003/0.0054 0.725/3.1 0.0500 0.0500]; 175 | a3 = annotation('textbox',dim,'String','K3'); 176 | a3.Color = 'red'; 177 | a3.FontSize = 12; 178 | a3.LineStyle = 'none'; 179 | 180 | 181 | axis([0 0.02 0 1.05]); 182 | ylabel('Mutual information (bit)'); 183 | xlabel('E_{th}'); 184 | legend('p_t = 1, p_n =0.001','p_t = 1, p_n =0.001 (\rho_1 = \rho_2)','p_t = 1, p_n =0.003','p_t = 1.5, p_n =0.001') 185 | 186 | %mesh(rho1,rho2,mi); 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /sim07/ray_model.m: -------------------------------------------------------------------------------- 1 | function h = ray_model(d,taps) 2 | % generate the exponential rayleigh model 3 | % inputs: 4 | % d: the distance between two objects 5 | % taps: the delay taps 6 | % output: 7 | % h: the exponential Rayleigh model 8 | 9 | lamda = 3; 10 | 11 | h_cg = 5*d^(-lamda/2); 12 | 13 | pow_h = exp(-(0:taps-1)); 14 | pow_h = h_cg*pow_h/norm(pow_h); 15 | 16 | h = (randn(1,1) + 1i*randn(1,1)) * sqrt(pow_h); -------------------------------------------------------------------------------- /sim07/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangpu03/physical-key-generation/5244028d6634e612f221823e3c1b653b6df1734a/sim07/readme.md -------------------------------------------------------------------------------- /sim07/receiver_design.m: -------------------------------------------------------------------------------- 1 | function [y,y_cp] = receiver_design(y_d, y_b, n_ofdm, n_cp, n_frame, n_L) 2 | % combinaiton of two signals 3 | 4 | sym_rem = mod(n_ofdm-mod(length(y_d),n_ofdm),n_ofdm); 5 | padding = repmat(0+0i,sym_rem,1); 6 | y_d_padded = [y_d;padding]; 7 | 8 | sym_rem = mod(n_ofdm-mod(length(y_b),n_ofdm),n_ofdm); 9 | padding = repmat(0+0i,sym_rem,1); 10 | y_b_padded = [y_b;padding]; 11 | 12 | y = y_d_padded+y_b_padded; 13 | 14 | % calculate the desired information at receivering devices 15 | n_fft = n_ofdm - n_cp; 16 | zb = y(n_L:n_cp) - y(n_fft+n_L:n_fft+n_cp); 17 | for n = 1:1:n_frame-1 18 | zb =[zb(:); (y(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 19 | end 20 | 21 | zd = y(n_L:n_cp) + y(n_fft+n_L:n_fft+n_cp); 22 | for n = 1:1:n_frame-1 23 | zd =[zd(:); (y(n*n_ofdm+n_L:n*n_ofdm+n_cp)+y(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 24 | end 25 | y_cp = zb .* zd; 26 | -------------------------------------------------------------------------------- /sim07/skr_snr.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = skr_snr(data_ofdm, n_ofdm, n_cp ,n_frame, cor, d_e1, snr) 2 | 3 | pt = 10^(-2); 4 | %snr = 100; 5 | alpha = 0.3 + 1i*0.4; 6 | pw_noise = pt/10^(snr/10); 7 | 8 | d = [8, 7, 3]; 9 | taps = [8, 7, 3]; 10 | n_L = max(taps(1),taps(2))+taps(3)-1; 11 | 12 | h1 = ray_model(d(1),taps(1)); 13 | h2 = ray_model(d(2),taps(2)); 14 | 15 | h_12 = ray_model(d(3),taps(3)); 16 | h_21 = h_12; 17 | 18 | cor_h1_he = cor; 19 | cor_h12_he2 = cor; 20 | 21 | % assume Eve locate closer to device 1 22 | %cor = 0; 23 | he = eave_ray_model(h1,cor_h1_he,d(1)); 24 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 25 | 26 | %d_e1 = 1; 27 | tap_e1 = 1; 28 | h_e1 = ray_model(d_e1,tap_e1); 29 | 30 | % all transmissions in ambient backscatter communication 31 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 32 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 33 | 34 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 35 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 36 | 37 | y1_b = ofdm_trans(back2, h_12, pw_noise); 38 | y2_b = ofdm_trans(back1, h_12, pw_noise); 39 | 40 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 41 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 42 | 43 | v_y1_cp = mean(abs(y1_cp)); 44 | v_y2_cp = mean(abs(y2_cp)); 45 | 46 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 47 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 48 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 49 | 50 | 51 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 52 | v_ye1_cp = mean(abs(ye1_cp)); 53 | v_ye2_cp = mean(abs(ye2_cp)); 54 | -------------------------------------------------------------------------------- /sim07/skr_snr_trad.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = skr_snr_trad(data_ofdm, n_ofdm, n_cp ,n_frame, cor, d_e1, snr) 2 | 3 | pt = 1; 4 | %snr = 100; 5 | alpha = 0.3 + 1i*0.4; 6 | pw_noise = pt/10^(snr/10); 7 | 8 | d = [8, 7, 3]; 9 | taps = [8, 7, 3]; 10 | n_L = max(taps(1),taps(2))+taps(3)-1; 11 | 12 | h1 = ray_model(d(1),taps(1)); 13 | h2 = ray_model(d(2),taps(2)); 14 | 15 | h_12 = ray_model(d(3),taps(3)); 16 | h_21 = h_12; 17 | 18 | % 假设h1信道和h3信道一摸一样,只考虑两个设备之间的信道,将其作为窃听信道 19 | cor_h1_he = 1; 20 | cor_h12_he2 = cor; 21 | 22 | % assume Eve locate closer to device 1 23 | %cor = 0; 24 | he = eave_ray_model(h1,cor_h1_he,d(1)); 25 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 26 | 27 | %d_e1 = 1; 28 | tap_e1 = 1; 29 | h_e1 = ray_model(d_e1,tap_e1); 30 | 31 | % all transmissions in ambient backscatter communication 32 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 33 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 34 | 35 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 36 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 37 | 38 | y1_b = ofdm_trans(back2, h_12, pw_noise); 39 | y2_b = ofdm_trans(back1, h_12, pw_noise); 40 | 41 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 42 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 43 | 44 | v_y1_cp = mean(abs(y1_cp)); 45 | v_y2_cp = mean(abs(y2_cp)); 46 | 47 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 48 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 49 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 50 | 51 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 52 | v_ye1_cp = mean(abs(ye1_cp)); 53 | v_ye2_cp = mean(abs(ye2_cp)); 54 | -------------------------------------------------------------------------------- /sim07/test_corr.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | h_ab = randn(1,5000) + 1i*randn(1,5000); 4 | r2_d = 0.9; 5 | h_ae = r2_d*h_ab + sqrt(1-r2_d^2)*(randn(1,5000) + 1i*randn(1,5000)); 6 | cor = corrcoef(h_ab,h_ae) 7 | cor_abs = corrcoef(abs(h_ab),abs(h_ae)) 8 | 9 | exp_PDP = exp(-(0:10-1)); 10 | exp_PDP = exp_PDP/norm(exp_PDP); 11 | 12 | h_ab_ofdm=(randn(5000,1)+1i*randn(5000,1))*sqrt(exp_PDP/2); 13 | 14 | h_ae_ofdm = zeros(5000,10); 15 | for i = 1:length(exp_PDP) 16 | h_ae_ofdm(:,i) = r2_d*h_ab_ofdm(:,i) + sqrt(exp_PDP(i)/2)*sqrt(1-r2_d^2)*(randn(5000,1) + 1i*randn(5000,1)); 17 | end 18 | 19 | cor_ofdm = corrcoef(h_ab_ofdm,h_ae_ofdm) 20 | 21 | 22 | % h_ae_ofdm2 = zeros(5000,10); 23 | % h_ae_ofdm2 = r2_d*h_ab_ofdm .+ sqrt(1-r2_d^2)*randn(1,1) + 1i*randn(1,1) 24 | 25 | -------------------------------------------------------------------------------- /sim08/Jakes_Flat.m: -------------------------------------------------------------------------------- 1 | function [h,tf]=Jakes_Flat(fd,Ts,Ns,t0,E0,phi_N) 2 | % Inputs: 3 | % fd,Ts,Ns : Doppler frequency, sampling time, number of samples 4 | % t0, E0 : initial time, channel power 5 | % phi_N : inital phase of the maximum Doppler frequency sinusoid 6 | % Outputs: 7 | % h, tf : complex fading vector, current time 8 | if nargin<6 9 | phi_N=0; 10 | end 11 | if nargin<5 12 | E0=1; 13 | end 14 | if nargin<4 15 | t0=0; 16 | end 17 | N0 = 8; % As suggested by Jakes 18 | N = 4*N0+2; % an accurate approximation 19 | wd = 2*pi*fd; % Maximum Doppler frequency[rad] 20 | t = t0+[0:Ns-1]*Ts; 21 | tf = t(end)+Ts; % Time vector and Final time 22 | coswt=[sqrt(2)*cos(wd*t); 2*cos(wd*cos(2*pi/N*[1:N0]')*t)]; % Eq.(2.26) 23 | h = E0/sqrt(2*N0+1) * exp(j*[phi_N pi/(N0+1)*[1:N0]])*coswt; % Eq.(2.23) 24 | 25 | -------------------------------------------------------------------------------- /sim08/ambc_ofdm.m: -------------------------------------------------------------------------------- 1 | % consists of all precedures of the OFDM 2 | % 3 | clear; 4 | clc; 5 | 6 | %% simulation parameters 7 | d = [8, 7, 3]; 8 | taps = [8, 7, 3]; 9 | n_L = max(taps(1),taps(2))+taps(3)-1; 10 | 11 | h1 = ray_model(d(1),taps(1)); 12 | h2 = ray_model(d(2),taps(2)); 13 | 14 | h_12 = ray_model(d(3),taps(3)); 15 | 16 | cor_h1_he = 0; 17 | cor_h12_he1 = 0; 18 | 19 | he = eave_ray_model(h1,0,d(1)); 20 | h_e1 = eave_ray_model(h_12,0,d(3)); 21 | 22 | 23 | n_fft = 128; % IFFT/FFT size 24 | n_cp = n_fft/4; % size of cyclic prefix extension 25 | n_frame = 1; % the acount of the OFDM frame 26 | n_ofdm = n_fft + n_cp; 27 | 28 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 29 | mod_method = 'QPSK'; 30 | % calculate modulation order from modulation method 31 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 32 | mod_order = find(ismember(mod_methods, mod_method)); 33 | % generate the data 34 | rand_ints_gen = randi(2,n_fft*mod_order*n_frame,1)-1; 35 | save data_input.txt -ascii rand_ints_gen 36 | rand_ints = load("data_input.txt"); 37 | 38 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, 0); 39 | data_cp_pwr = mean(abs(data_ofdm).^2) 40 | 41 | 42 | 43 | pt = 1; 44 | snr = 15; 45 | alpha = 0.3 + 1i*0.4; 46 | pw_noise = pt/10^(snr/10); 47 | 48 | % all transmissions in ambient backscatter communication 49 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 50 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 51 | 52 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 53 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 54 | 55 | y1_b = ofdm_trans(back2, h_12, pw_noise); 56 | y2_b = ofdm_trans(back1, h_12, pw_noise); 57 | 58 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 59 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 60 | 61 | v_y1_cp = mean(abs(y1_cp)); 62 | v_y2_cp = mean(abs(y2_cp)); 63 | 64 | 65 | -------------------------------------------------------------------------------- /sim08/ambc_ofdm_eve.m: -------------------------------------------------------------------------------- 1 | % consists of all precedures of the OFDM 2 | % 3 | clear; 4 | clc; 5 | 6 | % simulation parameters 7 | 8 | n_fft = 128; % IFFT/FFT size 9 | n_cp = n_fft/4; % size of cyclic prefix extension 10 | n_frame = 1; % the acount of the OFDM frame 11 | n_ofdm = n_fft + n_cp; 12 | 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | 20 | h_12 = ray_model(d(3),taps(3)); 21 | h_21 = h_12; 22 | 23 | cor_h1_he = 1; 24 | cor_h12_he2 = 1; 25 | 26 | % assume Eve locate closer to device 1 27 | cor = 0; 28 | he = eave_ray_model(h1,cor_h1_he,d(1)); 29 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 30 | 31 | d_e1 = 1; 32 | tap_e1 = 1; 33 | h_e1 = ray_model(d_e1,tap_e1); 34 | 35 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 36 | mod_method = 'QPSK'; 37 | % calculate modulation order from modulation method 38 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 39 | mod_order = find(ismember(mod_methods, mod_method)); 40 | % generate the data 41 | rand_ints_gen = randi(2,n_fft*mod_order*n_frame,1)-1; 42 | save data_input.txt -ascii rand_ints_gen 43 | rand_ints = load("data_input.txt"); 44 | 45 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, 0); 46 | 47 | pt = 1; 48 | snr = 40; 49 | alpha = 0.3 + 1i*0.4; 50 | pw_noise = pt/10^(snr/10); 51 | 52 | % all transmissions in ambient backscatter communication 53 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 54 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 55 | 56 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 57 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 58 | 59 | y1_b = ofdm_trans(back2, h_12, pw_noise); 60 | y2_b = ofdm_trans(back1, h_12, pw_noise); 61 | 62 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 63 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 64 | 65 | v_y1_cp = mean(abs(y1_cp)); 66 | v_y2_cp = mean(abs(y2_cp)); 67 | 68 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 69 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 70 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 71 | 72 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 73 | v_ye1_cp = mean(abs(ye1_cp)); 74 | v_ye2_cp = mean(abs(ye2_cp)); -------------------------------------------------------------------------------- /sim08/eave_ray_model.m: -------------------------------------------------------------------------------- 1 | function h = eave_ray_model(h_b,cor,d) 2 | % generate a exponential rayleigh model that is correlated to other 3 | % Raymodel 4 | % inputs: 5 | % d: the distance between two objects 6 | % cor: correlation coefficient 7 | % h_b: the base Rayleigh channel model 8 | % output: 9 | % h: the exponential Rayleigh model correlated to channel h 10 | lamda = 3; 11 | 12 | h_cg = d^(-lamda/2); 13 | 14 | pow_h = exp(-(0:length(h_b)-1)); 15 | pow_h = h_cg*pow_h/norm(pow_h); 16 | 17 | h = cor*h_b + sqrt(1-cor^2).*sqrt(pow_h).* (randn(1,length(h_b)) + 1i*randn(1,length(h_b))); 18 | -------------------------------------------------------------------------------- /sim08/evea_design.m: -------------------------------------------------------------------------------- 1 | function [ye1_cp, ye2_cp] = evea_design(y_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L) 2 | % 3 | 4 | sym_rem = mod(n_ofdm-mod(length(y_d),n_ofdm),n_ofdm); 5 | padding = repmat(0+0i,sym_rem,1); 6 | y_d_padded = [y_d;padding]; 7 | 8 | sym_rem = mod(n_ofdm-mod(length(y_b_e1),n_ofdm),n_ofdm); 9 | padding = repmat(0+0i,sym_rem,1); 10 | y_b_e1_padded = [y_b_e1;padding]; 11 | 12 | sym_rem = mod(n_ofdm-mod(length(y_b_e2),n_ofdm),n_ofdm); 13 | padding = repmat(0+0i,sym_rem,1); 14 | y_b_e2_padded = [y_b_e2;padding]; 15 | 16 | y_e2 = y_d_padded+y_b_e2_padded; 17 | 18 | y_e1 = y_d_padded+y_b_e1_padded; 19 | % calculate the desired information at receivering devices 20 | n_fft = n_ofdm - n_cp; 21 | zb_e2 = y_e2(n_L:n_cp) - y_e2(n_fft+n_L:n_fft+n_cp); 22 | for n = 1:1:n_frame-1 23 | zb_e2 =[zb_e2(:); (y_e2(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y_e2(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 24 | end 25 | 26 | zd_e2 = y_e2(n_L:n_cp) + y_e2(n_fft+n_L:n_fft+n_cp); 27 | for n = 1:1:n_frame-1 28 | zd_e2 =[zd_e2(:); (y_e2(n*n_ofdm+n_L:n*n_ofdm+n_cp)+y_e2(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 29 | end 30 | ye2_cp = zb_e2 .* zd_e2; %%发射信号和直射信号相乘,得到第一类窃听方法 31 | 32 | n_fft = n_ofdm - n_cp; 33 | zb_e1 = y_e1(n_L:n_cp) - y_e1(n_fft+n_L:n_fft+n_cp); 34 | for n = 1:1:n_frame-1 35 | zb_e1 =[zb_e1(:); (y_e1(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y_e1(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 36 | end 37 | 38 | ye1_cp = zb_e1 .* zb_e2; %%两个反射信号相乘,得到第二类窃听方法 39 | -------------------------------------------------------------------------------- /sim08/mi_dist.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = mi_dist(data_ofdm, n_ofdm, n_cp ,n_frame, d, taps, snr) 2 | pt = 10^(-2); 3 | %snr = 100; 4 | alpha = 0.3 + 1i*0.4; 5 | pw_noise = pt/10^(snr/10); 6 | 7 | n_L = max(taps(1),taps(2))+taps(3)-1; 8 | 9 | h1 = ray_model(d(1),taps(1)); 10 | h2 = ray_model(d(2),taps(2)); 11 | 12 | h_12 = ray_model(d(3),taps(3)); 13 | h_21 = h_12; 14 | 15 | cor = 0; 16 | cor_h1_he = cor; 17 | cor_h12_he2 = cor; 18 | 19 | % assume Eve locate closer to device 1 20 | %cor = 0; 21 | he = eave_ray_model(h1,cor_h1_he,d(1)); 22 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 23 | 24 | d_e1 = 1; 25 | tap_e1 = 1; 26 | h_e1 = ray_model(d_e1,tap_e1); 27 | 28 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 29 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 30 | 31 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 32 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 33 | 34 | y1_b = ofdm_trans(back2, h_12, pw_noise); 35 | y2_b = ofdm_trans(back1, h_12, pw_noise); 36 | 37 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 38 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 39 | 40 | v_y1_cp = mean(abs(y1_cp)); 41 | v_y2_cp = mean(abs(y2_cp)); 42 | 43 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 44 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 45 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 46 | 47 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 48 | v_ye1_cp = mean(abs(ye1_cp)); 49 | v_ye2_cp = mean(abs(ye2_cp)); -------------------------------------------------------------------------------- /sim08/mi_snr.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr(data_ofdm, n_ofdm, n_cp ,n_frame, snr) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | h_12 = ray_model(d(3),taps(3)); 20 | 21 | pt = 10^(-2); 22 | %snr = 100; 23 | alpha = 0.3 + 1i*0.4; 24 | pw_noise = pt/10^(snr/10); 25 | 26 | % all transmissions in ambient backscatter communication 27 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 28 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 29 | 30 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 31 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 32 | 33 | y1_b = ofdm_trans(back2, h_12, pw_noise); 34 | y2_b = ofdm_trans(back1, h_12, pw_noise); 35 | 36 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 37 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 38 | 39 | v_y1_cp = mean(abs(y1_cp)); 40 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim08/mi_snr2.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr2(data_ofdm, n_ofdm, n_cp ,n_frame, snr) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [5, 4, 1]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | h_12 = ray_model(d(3),taps(3)); 20 | 21 | pt = 10^(-2); 22 | %snr = 100; 23 | alpha = 0.3 + 1i*0.4; 24 | pw_noise = pt/10^(snr/10); 25 | 26 | % all transmissions in ambient backscatter communication 27 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 28 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 29 | 30 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 31 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 32 | 33 | y1_b = ofdm_trans(back2, h_12, pw_noise); 34 | y2_b = ofdm_trans(back1, h_12, pw_noise); 35 | 36 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 37 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 38 | 39 | v_y1_cp = mean(abs(y1_cp)); 40 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim08/mi_snr_ne.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr_ne(data_ofdm, n_ofdm, n_cp ,n_frame, snr, cor) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | h_12 = ray_model(d(3),taps(3)); 20 | 21 | h1_t = ray_model_cor(h1,cor,d(1)); 22 | h2_t = ray_model_cor(h2,cor,d(2)); 23 | h_12_t = ray_model_cor(h_12,cor,d(3)); 24 | 25 | 26 | pt = 10^(-2); 27 | %snr = 100; 28 | alpha = 0.3 + 1i*0.4; 29 | pw_noise = pt/10^(snr/10); 30 | 31 | % all transmissions in ambient backscatter communication 32 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 33 | 34 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 35 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 36 | y1_b = ofdm_trans(back2, h_12, pw_noise); 37 | 38 | y1_d_t = ofdm_trans(data_ofdm, h1_t, pw_noise); 39 | back1_t = ofdm_back(y1_d_t, alpha, n_ofdm, n_frame); 40 | y2_b_t = ofdm_trans(back1_t, h_12_t, pw_noise); 41 | 42 | y2_d_t = ofdm_trans(data_ofdm, h2_t, pw_noise); 43 | 44 | 45 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 46 | [y2,y2_cp] = receiver_design(y2_d_t, y2_b_t, n_ofdm, n_cp, n_frame, n_L); 47 | 48 | v_y1_cp = mean(abs(y1_cp)); 49 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim08/mi_snr_ne_trad.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr_ne_trad(data_ofdm, n_ofdm, n_cp ,n_frame, snr, cor) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h1 = ray_model(d(1),taps(1)); 18 | h2 = ray_model(d(2),taps(2)); 19 | h_12 = ray_model(d(3),taps(3)); 20 | 21 | h1_t = ray_model_cor(h1,1,d(1)); 22 | h2_t = ray_model_cor(h2,1,d(2)); 23 | h_12_t = ray_model_cor(h_12,cor,d(3)); 24 | 25 | pt = 10^(-2); 26 | %snr = 100; 27 | alpha = 0.3 + 1i*0.4; 28 | pw_noise = pt/10^(snr/10); 29 | 30 | % all transmissions in ambient backscatter communication 31 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 32 | 33 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 34 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 35 | y1_b = ofdm_trans(back2, h_12, pw_noise); 36 | 37 | y1_d_t = ofdm_trans(data_ofdm, h1_t, pw_noise); 38 | back1_t = ofdm_back(y1_d_t, alpha, n_ofdm, n_frame); 39 | y2_b_t = ofdm_trans(back1_t, h_12_t, pw_noise); 40 | 41 | y2_d_t = ofdm_trans(data_ofdm, h2_t, pw_noise); 42 | 43 | 44 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 45 | [y2,y2_cp] = receiver_design(y2_d_t, y2_b_t, n_ofdm, n_cp, n_frame, n_L); 46 | 47 | v_y1_cp = mean(abs(y1_cp)); 48 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim08/mi_snr_ne_trad2.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp] = mi_snr_ne_trad2(data_ofdm, n_ofdm, n_cp ,n_frame, snr, cor) 2 | % inputs: 3 | % data_ofdm: the modulated data with OFDM 4 | % n_ofdm: the number of the ofdm symbols in a ofdm frame 5 | % n_cp: 6 | % n_frame: the number of the ofdm frames 7 | % snr: signal to noise rate (dB) 8 | % outputs: 9 | % v_y1_cp: the ofdm symbols within CP part of devices 1 10 | % v_y2_cp: the ofdm symbols within CP part of devices 2 11 | 12 | %% simulation parameters 13 | d = [8, 7, 3]; 14 | taps = [8, 7, 3]; 15 | n_L = max(taps(1),taps(2))+taps(3)-1; 16 | 17 | h_12 = ray_model(d(3),taps(3)); 18 | 19 | h_12_t = ray_model_cor(h_12,cor,d(3)); 20 | 21 | pt = 10^(-2); 22 | %snr = 100; 23 | pw_noise = pt/10^(snr/10); 24 | 25 | % all transmissions in ambient backscatter communication 26 | y1_d = ofdm_trans(data_ofdm, h_12, pw_noise); 27 | y1_d_t = ofdm_trans(data_ofdm, h_12_t, pw_noise); 28 | 29 | [y1_cp] = receiver_design2(y1_d, n_ofdm, n_cp, n_frame, n_L); 30 | [y2_cp] = receiver_design2(y1_d_t, n_ofdm, n_cp, n_frame, n_L); 31 | 32 | v_y1_cp = mean(abs(y1_cp)); 33 | v_y2_cp = mean(abs(y2_cp)); -------------------------------------------------------------------------------- /sim08/ofdm_back.m: -------------------------------------------------------------------------------- 1 | function back_data = ofdm_back(data, alpha, n_ofdm, n_frame) 2 | % inputs: 3 | % data: the ofdm data before backscatter 4 | % alpha: backscatter coefficient 5 | % n_ofdm: the number of IFFT of a ofdm frame 6 | % n_frame: the number of frame of the all data 7 | % outputs: 8 | % back_data: the ofdm data after backscatter 9 | 10 | 11 | % the designing of the backscatter waveform at the user 1 12 | bc_signal_fh = ones(n_ofdm/2,1); 13 | bc_signal_bh = ones(n_ofdm/2,1)-2; 14 | bc_signal = [bc_signal_fh; bc_signal_bh]; 15 | bc_signal = repmat(bc_signal,n_frame,1); 16 | 17 | % backscatter operation of the signal from user1 18 | sym_rem = mod(length(data),n_ofdm); 19 | padding_bc = zeros(sym_rem,1); %pad zero 20 | bc_signal = [bc_signal;padding_bc]; 21 | size(bc_signal); 22 | size(data); 23 | back_data = alpha*bc_signal.*data; 24 | -------------------------------------------------------------------------------- /sim08/ofdm_module.m: -------------------------------------------------------------------------------- 1 | function ofdm_data = ofdm_module(data,mod_method, n_fft, n_cp, cp_flag) 2 | % modulate the data with OFDM 3 | % inputs: 4 | % data: input raw data with bits, length = n_fft*mod_order*n_frame 5 | % mod_method: symbol modulation 6 | % n_fft: IFFT/FFT size 7 | % n_cp: size of cyclic prefix extension 8 | % n_frame: the acount of the OFDM frame 9 | % cp_flag: 1--cp, 0--guard 10 | %output: 11 | % ofdm_data: modulated OFDM data 12 | 13 | if nargin < 4 14 | cp_flag = 1; 15 | end 16 | 17 | %n_ofdm = n_fft+n_cp; 18 | % calculate modulation order from modulation method 19 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 20 | mod_order = find(ismember(mod_methods, mod_method)); 21 | 22 | % input data to binary stream 23 | rand_bits = dec2bin(data(:)); 24 | 25 | % binary stream to symbols 26 | % Parse binary stream into mod_order bit symbols 27 | % pads input signal to appropriate length 28 | sym_rem = mod(mod_order-mod(length(rand_bits),mod_order),mod_order); 29 | padding = repmat('0',sym_rem,1); 30 | rand_bits_padded = [rand_bits;padding]; 31 | cons_data = reshape(rand_bits_padded, mod_order,length(rand_bits_padded)/mod_order)'; 32 | cons_sym_id = bin2dec(cons_data); 33 | 34 | % symbol modulation codebook 35 | % BPSK 36 | if mod_order == 1 37 | mod_ind = 2^(mod_order-1); 38 | n = 0:pi/mod_ind:2*pi-pi/mod_ind; 39 | in_phase = cos(n); 40 | quadrature = sin(n); 41 | symbol_book = (in_phase+quadrature*1i)'; 42 | end 43 | 44 | % phase shift keying about unit circle 45 | if mod_order == 2 || mod_order ==3 46 | mod_ind = 2^(mod_order-1); 47 | n = 0:pi/mod_ind:2*pi-pi/mod_ind; 48 | in_phase = cos(n+pi/4); 49 | quadrature = sin(n+pi/4); 50 | symbol_book = (in_phase+quadrature*1i)'; 51 | end 52 | 53 | % 16QAM, 64QAM modulaiton 54 | if mod_order ==4 || mod_order ==6 55 | mod_ind = 2^(mod_order-2); 56 | in_phase = repmat(linspace(-1,1,mod_ind),mod_ind,1); 57 | quadrature = repmat(linspace(-1,1,mod_ind)',1,mod_ind); 58 | symbol_book = in_phase(:)+quadrature(:)*1i; 59 | end 60 | 61 | % 32 QAM modulation 62 | % generate 6x6 constellation and removes corners 63 | if mod_order ==5 64 | mod_ind = 6; 65 | in_phase = repmat(linspace(-1,1,mod_ind),mod_ind,1); 66 | quadrature = repmat(linspace(-1,1,mod_ind)',1,mod_ind); 67 | symbol_book = in_phase(:)+quadrature(:)*1i; 68 | symbol_book = symbol_book([2:5 7:30 32:35]); 69 | end 70 | 71 | % modulate data according to symbol_book 72 | X = symbol_book(cons_sym_id+1); 73 | %size_X = size(X) 74 | 75 | % use IFFT to move to time domain 76 | % pad input signal to appropriate lengthmod(length(X),n_fft) 77 | fft_rem = mod(n_fft-mod(length(X),n_fft),n_fft); 78 | X_padded = [X;zeros(fft_rem,1)]; 79 | X_blocks = reshape(X_padded, n_fft,length(X_padded)/n_fft); 80 | x = ifft(X_blocks); 81 | %data_x_pwr = mean(abs(x).^2) 82 | % add cyclic prefix extension and shift from parallel to serial 83 | guard_zp = zeros(n_cp,1); 84 | guard_op = ones(n_cp,1)*(1+1i)/sqrt(2); 85 | guard_pre = [0;(1+1i)/sqrt(2)]; 86 | guard_pre = repmat(guard_pre,n_cp/2,1); 87 | 88 | if cp_flag == 1 89 | x_cp = [x(end-n_cp+1:end,:);x]; 90 | elseif cp_flag == 2 91 | x_cp = [guard_zp;x(1:n_fft-n_cp,:);guard_zp]; 92 | elseif cp_flag == 3 93 | x_cp = [guard_op;x(1:n_fft-n_cp,:);guard_op]; 94 | elseif cp_flag == 4 95 | x_cp = [guard_pre;x(1:n_fft-n_cp,:);guard_pre]; 96 | end 97 | 98 | ofdm_data = x_cp(:); 99 | 100 | ofdm_data = ofdm_data/sqrt(mean(abs(ofdm_data).^2)); 101 | 102 | 103 | -------------------------------------------------------------------------------- /sim08/ofdm_trans.m: -------------------------------------------------------------------------------- 1 | function channel_data = ofdm_trans(ofdm_data, h, noise_pw) 2 | % inputs: 3 | % ofdm_data: modulated data for transmitting 4 | % h: the Rayleigh channel that data will go through 5 | % noise_pw: the noise power recieved at receiver 6 | % output: 7 | % channel data: the received data at receiver, including data signal and 8 | % noise signal 9 | 10 | channel_data = conv(ofdm_data,h); 11 | 12 | 13 | noise = normrnd(0,sqrt(noise_pw),size(channel_data))+normrnd(0,sqrt(noise_pw),size(channel_data))*1i; 14 | channel_data = channel_data+noise; -------------------------------------------------------------------------------- /sim08/plot_mi_bdr_preamble.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | datestr(now) 4 | addpath('E:\Github\physical-key-generation\MIToolbox-master\matlab'); 5 | 6 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 7 | mod_method = 'QPSK'; 8 | % calculate modulation order from modulation method 9 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 10 | mod_order = find(ismember(mod_methods, mod_method)); 11 | 12 | % 该数据可以生成一次之后可以永久使用,保证每次调制的数据一致 13 | % rand_ints_gen = randi(2,10000,1)-1; 14 | % save data_input.txt -ascii rand_ints_gen 15 | rand_ints = load("data_input.txt"); 16 | 17 | num_mc = 50000; 18 | 19 | snr = 0:3:30; 20 | v1 = zeros(num_mc, length(snr)); 21 | v2 = zeros(num_mc, length(snr)); 22 | 23 | %% 24 | % nfft = 256, K =1 25 | n_fft = 256; 26 | n_cp = n_fft/4; % size of cyclic prefix extension 27 | n_ofdm = n_fft + n_cp; 28 | K=1; 29 | c_flag = 1; 30 | % generate the data 31 | rand_ints_1256 = rand_ints(1:n_fft*mod_order*K,:); 32 | data_ofdm = ofdm_module(rand_ints_1256, mod_method, n_fft, n_cp, c_flag); 33 | 34 | for i = 1:length(snr) 35 | for j = 1:num_mc 36 | [v1(j,i),v2(j,i)] = mi_snr(data_ofdm, n_ofdm,n_cp, K, snr(i)); 37 | end 38 | end 39 | 40 | mean_v1 = repmat(mean(v1), num_mc,1); 41 | mean_v2 = repmat(mean(v2), num_mc,1); 42 | 43 | v1_bit = double(v1>= mean_v1); 44 | v2_bit = double(v2>= mean_v2); 45 | 46 | for i = 1:length(snr) 47 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 48 | end 49 | 50 | v1_cp = v1; 51 | v2_cp = v2; 52 | v1_bit_cp = v1_bit; 53 | v2_bit_cp = v2_bit; 54 | mi_bit_cp = mi_bit; 55 | 56 | 57 | %% 58 | % nfft = 256, K =1, ZP=2 59 | n_fft = 256; 60 | n_cp = n_fft/4; % size of cyclic prefix extension 61 | n_ofdm = n_fft + n_cp; 62 | K=1; 63 | c_flag = 2; 64 | % generate the data 65 | rand_ints_1256 = rand_ints(1:n_fft*mod_order*K,:); 66 | data_ofdm = ofdm_module(rand_ints_1256, mod_method, n_fft, n_cp, c_flag); 67 | 68 | for i = 1:length(snr) 69 | for j = 1:num_mc 70 | [v1(j,i),v2(j,i)] = mi_snr(data_ofdm, n_ofdm,n_cp, K, snr(i)); 71 | end 72 | end 73 | 74 | mean_v1 = repmat(mean(v1), num_mc,1); 75 | mean_v2 = repmat(mean(v2), num_mc,1); 76 | 77 | v1_bit = double(v1>= mean_v1); 78 | v2_bit = double(v2>= mean_v2); 79 | 80 | for i = 1:length(snr) 81 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 82 | end 83 | 84 | v1_zp = v1; 85 | v2_zp = v2; 86 | 87 | v1_bit_zp = v1_bit; 88 | v2_bit_zp = v2_bit; 89 | mi_bit_zp = mi_bit; 90 | 91 | %% 92 | % nfft = 256, K =1, OP=3 93 | n_fft = 256; 94 | n_cp = n_fft/4; % size of cyclic prefix extension 95 | n_ofdm = n_fft + n_cp; 96 | K=1; 97 | c_flag = 3; 98 | % generate the data 99 | rand_ints_1256 = rand_ints(1:n_fft*mod_order*K,:); 100 | data_ofdm = ofdm_module(rand_ints_1256, mod_method, n_fft, n_cp, c_flag); 101 | 102 | for i = 1:length(snr) 103 | for j = 1:num_mc 104 | [v1(j,i),v2(j,i)] = mi_snr(data_ofdm, n_ofdm,n_cp, K, snr(i)); 105 | end 106 | end 107 | 108 | mean_v1 = repmat(mean(v1), num_mc,1); 109 | mean_v2 = repmat(mean(v2), num_mc,1); 110 | 111 | v1_bit = double(v1>= mean_v1); 112 | v2_bit = double(v2>= mean_v2); 113 | 114 | for i = 1:length(snr) 115 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 116 | end 117 | 118 | v1_op = v1; 119 | v2_op = v2; 120 | 121 | v1_bit_op = v1_bit; 122 | v2_bit_op = v2_bit; 123 | mi_bit_op = mi_bit; 124 | 125 | %% 126 | % nfft = 256, K =1, preamble=4 127 | n_fft = 256; 128 | n_cp = n_fft/4; % size of cyclic prefix extension 129 | n_ofdm = n_fft + n_cp; 130 | K=1; 131 | c_flag = 4; 132 | % generate the data 133 | rand_ints_1256 = rand_ints(1:n_fft*mod_order*K,:); 134 | data_ofdm = ofdm_module(rand_ints_1256, mod_method, n_fft, n_cp, c_flag); 135 | 136 | for i = 1:length(snr) 137 | for j = 1:num_mc 138 | [v1(j,i),v2(j,i)] = mi_snr(data_ofdm, n_ofdm,n_cp, K, snr(i)); 139 | end 140 | end 141 | 142 | mean_v1 = repmat(mean(v1), num_mc,1); 143 | mean_v2 = repmat(mean(v2), num_mc,1); 144 | 145 | v1_bit = double(v1>= mean_v1); 146 | v2_bit = double(v2>= mean_v2); 147 | 148 | for i = 1:length(snr) 149 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 150 | end 151 | 152 | v1_pre = v1; 153 | v2_pre = v2; 154 | 155 | v1_bit_pre = v1_bit; 156 | v2_bit_pre = v2_bit; 157 | mi_bit_pre = mi_bit; 158 | 159 | 160 | %% 161 | snr = 0:3:30; 162 | plot(snr, mi_bit_cp,'-d','LineWidth',1.5,'Color', '#77AC30'); 163 | hold on; 164 | plot(snr, mi_bit_zp,'r-x','LineWidth',1.5); 165 | hold on; 166 | plot(snr, mi_bit_op,'k-o','LineWidth',1.5); 167 | hold on; 168 | plot(snr, mi_bit_pre,'-s','LineWidth',1.5,'Color', '#0072BD'); 169 | grid on; 170 | axis([0 30 0.3 0.95]); 171 | legend('CP','ZP','OP','1-0 bits'); 172 | %legend('K = 1, N_{FFT} = 256','K = 3, N_{FFT} = 256','K = 1, N_{FFT} = 256','K = 3, N_{FFT} = 256','K = 1, N_{Guard} = 256','K = 1, N_{Guard} = 256','K = 1, N_{Guard}= 256,Noiseless'); 173 | ylabel('每比特互信息(bits)','Fontname','<宋体>'); 174 | xlabel('SNR (dB)'); 175 | 176 | %% 计算BDR 177 | bdr_cp = 1 - sum(v1_bit_cp == v2_bit_cp)/num_mc; 178 | bdr_zp = 1 - sum(v1_bit_zp == v2_bit_zp)/num_mc; 179 | bdr_op = 1 - sum(v1_bit_op == v2_bit_op)/num_mc; 180 | bdr_pre = 1 - sum(v1_bit_pre == v2_bit_pre)/num_mc; 181 | 182 | %% 183 | snr = 0:3:30; 184 | plot(snr, bdr_cp,'-d','LineWidth',1.5,'Color', '#77AC30'); 185 | hold on; 186 | plot(snr, bdr_zp,'r-x','LineWidth',1.5); 187 | hold on; 188 | plot(snr, bdr_op,'k-o','LineWidth',1.5); 189 | hold on; 190 | plot(snr, bdr_pre,'-s','LineWidth',1.5,'Color', '#0072BD'); 191 | grid on; 192 | axis([0 30 0.0 0.17]); 193 | legend('CP','ZP','OP','1-0 bits'); 194 | %legend('K = 1, N_{FFT} = 256','K = 3, N_{FFT} = 256','K = 1, N_{FFT} = 256','K = 3, N_{FFT} = 256','K = 1, N_{Guard} = 256','K = 1, N_{Guard} = 256','K = 1, N_{Guard}= 256,Noiseless'); 195 | ylabel('互异比特比率','Fontname','<宋体>'); 196 | xlabel('SNR (dB)'); 197 | datestr(now) -------------------------------------------------------------------------------- /sim08/plot_mi_dist.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | 4 | addpath('E:\Github\physical-key-generation\MIToolbox-master\matlab'); 5 | 6 | % modulation methods: BPSK, QPSK,16QAM, 32QAM,64QAM 7 | mod_method = 'QPSK'; 8 | % calculate modulation order from modulation method 9 | mod_methods = {'BPSK', 'QPSK','8PSK','16QAM', '32QAM','64QAM'}; 10 | mod_order = find(ismember(mod_methods, mod_method)); 11 | 12 | % 13 | % nfft = 256, K =1 14 | n_fft = 256; 15 | n_cp = n_fft/4; % size of cyclic prefix extension 16 | n_ofdm = n_fft + n_cp; 17 | K = 1; 18 | c_flag = 1; 19 | % generate the data 20 | % rand_ints_gen = randi(2,n_fft*mod_order*K,1)-1; 21 | % save data_input.txt -ascii rand_ints_gen 22 | rand_ints = load("data_input.txt"); 23 | rand_ints = rand_ints(1:n_fft*mod_order*K,:); 24 | data_ofdm = ofdm_module(rand_ints, mod_method, n_fft, n_cp, c_flag); 25 | num_sim = 50000; 26 | snr = 0:3:30; 27 | v1 = zeros(num_sim, length(snr)); 28 | v2 = zeros(num_sim, length(snr)); 29 | ve1 = zeros(num_sim, length(snr)); 30 | ve2 = zeros(num_sim, length(snr)); 31 | 32 | %% 33 | d = [8 7 3]; 34 | taps = [8 7 3]; 35 | for i = 1:length(snr) 36 | for j = 1:num_sim 37 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 38 | end 39 | end 40 | 41 | mean_v1 = repmat(mean(v1), num_sim,1); 42 | mean_v2 = repmat(mean(v2), num_sim,1); 43 | mean_ve1 = repmat(mean(ve1), num_sim,1); 44 | mean_ve2 = repmat(mean(ve2), num_sim,1); 45 | 46 | v1_bit = double(v1>= mean_v1); 47 | v2_bit = double(v2>= mean_v2); 48 | ve1_bit = double(ve1>= mean_ve1); 49 | ve2_bit = double(ve2>= mean_ve2); 50 | 51 | cmi_ve2 = zeros(1,length(snr)); 52 | cmi_ve1 = zeros(1,length(snr)); 53 | mi_bit = zeros(1,length(snr)); 54 | for i = 1:length(snr) 55 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 56 | end 57 | 58 | for i = 1:length(snr) 59 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 60 | end 61 | 62 | for i = 1:length(snr) 63 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 64 | end 65 | 66 | v1_873 = v1; 67 | v2_873 = v2; 68 | ve1_873 = ve1; 69 | ve2_873 = ve2; 70 | mi_bit_873 = mi_bit; 71 | cmi_ve2_873 = cmi_ve2; 72 | cmi_ve1_873 = cmi_ve1; 73 | 74 | %% 75 | d = [12 7 3]; 76 | taps = [12 7 3]; 77 | for i = 1:length(snr) 78 | for j = 1:num_sim 79 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 80 | end 81 | end 82 | mean_v1 = repmat(mean(v1), num_sim,1); 83 | mean_v2 = repmat(mean(v2), num_sim,1); 84 | mean_ve1 = repmat(mean(ve1), num_sim,1); 85 | mean_ve2 = repmat(mean(ve2), num_sim,1); 86 | 87 | v1_bit = double(v1>= mean_v1); 88 | v2_bit = double(v2>= mean_v2); 89 | ve1_bit = double(ve1>= mean_ve1); 90 | ve2_bit = double(ve2>= mean_ve2); 91 | 92 | cmi_ve2 = zeros(1,length(snr)); 93 | cmi_ve1 = zeros(1,length(snr)); 94 | mi_bit = zeros(1,length(snr)); 95 | for i = 1:length(snr) 96 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 97 | end 98 | 99 | for i = 1:length(snr) 100 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 101 | end 102 | 103 | for i = 1:length(snr) 104 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 105 | end 106 | 107 | v1_1273 = v1; 108 | v2_1273 = v2; 109 | ve1_1273 = ve1; 110 | ve2_1273 = ve2; 111 | mi_bit_1273 = mi_bit; 112 | cmi_ve2_1273 = cmi_ve2; 113 | cmi_ve1_1273 = cmi_ve1; 114 | 115 | 116 | %% 117 | d = [12 7 6]; 118 | taps = [12 7 6]; 119 | for i = 1:length(snr) 120 | for j = 1:num_sim 121 | [v1(j,i),v2(j,i),ve1(j,i),ve2(j,i)] = mi_dist(data_ofdm, n_ofdm, n_cp ,K, d, taps, snr(i)); 122 | end 123 | end 124 | 125 | mean_v1 = repmat(mean(v1), num_sim,1); 126 | mean_v2 = repmat(mean(v2), num_sim,1); 127 | mean_ve1 = repmat(mean(ve1), num_sim,1); 128 | mean_ve2 = repmat(mean(ve2), num_sim,1); 129 | 130 | v1_bit = double(v1>= mean_v1); 131 | v2_bit = double(v2>= mean_v2); 132 | ve1_bit = double(ve1>= mean_ve1); 133 | ve2_bit = double(ve2>= mean_ve2); 134 | 135 | cmi_ve2 = zeros(1,length(snr)); 136 | cmi_ve1 = zeros(1,length(snr)); 137 | mi_bit = zeros(1,length(snr)); 138 | for i = 1:length(snr) 139 | mi_bit(i) = mi(v1_bit(:,i),v2_bit(:,i)); 140 | end 141 | 142 | for i = 1:length(snr) 143 | cmi_ve2(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve2_bit(:,i)); 144 | end 145 | 146 | for i = 1:length(snr) 147 | cmi_ve1(i) = cmi(v1_bit(:,i),v2_bit(:,i),ve1_bit(:,i)); 148 | end 149 | 150 | v1_1276 = v1; 151 | v2_1276 = v2; 152 | ve1_1276 = ve1; 153 | ve2_1276 = ve2; 154 | mi_bit_1276 = mi_bit; 155 | cmi_ve2_1276 = cmi_ve2; 156 | cmi_ve1_1276 = cmi_ve1; 157 | 158 | 159 | plot(snr, mi_bit_873,'r-o','LineWidth',1.5); 160 | hold on; 161 | plot(snr, mi_bit_1273,'k-x','LineWidth',1.5); 162 | plot(snr, mi_bit_1276,'b-*','LineWidth',1.5); 163 | plot(snr, cmi_ve2_873,'r--s','LineWidth',1.5); 164 | plot(snr, cmi_ve2_1273,'k--^','LineWidth',1.5); 165 | plot(snr, cmi_ve2_1276,'b--v','LineWidth',1.5); 166 | plot(snr, mi_bit_873-cmi_ve2_873,'r-.v','LineWidth',1.5); 167 | plot(snr, mi_bit_1273-cmi_ve2_1273,'k-.s','LineWidth',1.5); 168 | plot(snr, mi_bit_1276-cmi_ve2_1276,'b-.d','LineWidth',1.5); 169 | hold off; 170 | grid on; 171 | 172 | axis([0 30 0 1.3]) 173 | txt = {'Red: d_1 = 8, d_2 = 7, d_{12} = 3 ','Black: d_1 = 12, d_2 = 7, d_{12} = 3','Blue: d_1 = 12, d_2 = 7, d_{12} = 6'}; 174 | annotation('textbox',[0.15,0.74,0.35,0.165],'LineStyle','-','LineWidth',1,'String',txt) 175 | 176 | elps1 = annotation('ellipse',[0.800 0.635 0.0500 0.0500]); 177 | elps1.LineWidth = 1.5; 178 | elps1.Color = '#D95319'; 179 | 180 | x = [0.770,0.820]; 181 | y = [0.52,0.635]; 182 | a1 = annotation('textarrow',x, y,'String','密钥生成速率','Fontname','<宋体>'); 183 | a1.Color = 'red'; 184 | a1.FontSize = 12; 185 | a1.LineWidth = 1.5; 186 | 187 | elps2 = annotation('ellipse',[0.6500 0.67 0.0500 0.0500]); 188 | elps2.LineWidth = 1.5; 189 | elps2.Color = '#D95319'; 190 | 191 | x2 = [0.60,0.6700]; 192 | y2 = [0.60,0.67]; 193 | a2 = annotation('textarrow',x2, y2,'String','互信息','Fontname','<宋体>'); 194 | a2.Color = 'red'; 195 | a2.FontSize = 12; 196 | a2.LineWidth = 1.5; 197 | 198 | elps3 = annotation('ellipse',[0.800 0.117 0.0500 0.0500]); 199 | elps3.LineWidth = 1.5; 200 | elps3.Color = '#D95319'; 201 | x3 = [0.77,0.830]; 202 | y3 = [0.25,0.17]; 203 | a3 = annotation('textarrow',x3, y3,'String','泄漏信息量','Fontname','<宋体>'); 204 | a3.Color = 'red'; 205 | a3.FontSize = 12; 206 | a3.LineWidth = 1.5; 207 | %ylabel('Information (bit)'); 208 | xlabel('SNR (dB)'); 209 | 210 | -------------------------------------------------------------------------------- /sim08/plot_mi_eth.m: -------------------------------------------------------------------------------- 1 | % plot_mi_eth.m 2 | 3 | clc; 4 | clear; 5 | 6 | d = [10 7 3]; 7 | alpha = 0.3 + 1i*0.4; 8 | 9 | lamda = 3; 10 | h = 5*d.^(-lamda/2); 11 | 12 | rho1 =0:0.01:1; 13 | rho2 =0:0.01:1; 14 | 15 | %% 16 | snr = 30; 17 | pt = 1; 18 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 19 | pw_noise = pt/10^(snr/10); 20 | 21 | E_th = 0:0.001:0.1; 22 | mi_max = zeros(1,length(E_th)); 23 | mi_diag_max = zeros(1,length(E_th)); 24 | for j = 1:length(E_th) 25 | mi = zeros(length(rho1),length(rho2)); 26 | for i = 1:length(rho1) 27 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 28 | if E1 < E_th(j) 29 | break; 30 | end 31 | end 32 | num_rho1 = i-1; 33 | 34 | for i = 1:length(rho2) 35 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 36 | if E2 < E_th(j) 37 | break; 38 | end 39 | end 40 | num_rho2 = i-1; 41 | 42 | for i = 1:num_rho1 43 | for k = 1:num_rho2 44 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 45 | end 46 | end 47 | 48 | mi_max (j) = max(max(mi)'); 49 | mi_diag_max(j) = max(diag(mi)); 50 | end 51 | 52 | 53 | %% 54 | snr = 25; 55 | pt = 1; 56 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 57 | pw_noise = pt/10^(snr/10); 58 | 59 | E_th = 0:0.001:0.1; 60 | mi_25_max = zeros(1,length(E_th)); 61 | mi_diag_25_max = zeros(1,length(E_th)); 62 | for j = 1:length(E_th) 63 | mi = zeros(length(rho1),length(rho2)); 64 | for i = 1:length(rho1) 65 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 66 | if E1 < E_th(j) 67 | break; 68 | end 69 | end 70 | num_rho1 = i-1; 71 | 72 | for i = 1:length(rho2) 73 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 74 | if E2 < E_th(j) 75 | break; 76 | end 77 | end 78 | num_rho2 = i-1; 79 | 80 | for i = 1:num_rho1 81 | for k = 1:num_rho2 82 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 83 | end 84 | end 85 | 86 | mi_25_max (j) = max(max(mi)'); 87 | %mi_diag_35_max(j) = max(diag(mi)); 88 | end 89 | 90 | %% 91 | snr = 30; 92 | pt = 1.5; 93 | P = 4*pt*abs(alpha)*h(1)*h(2)*h(3); 94 | pw_noise = 1/10^(snr/10); 95 | 96 | E_th = 0:0.001:0.1; 97 | mi_2_max = zeros(1,length(E_th)); 98 | mi_diag_2_max = zeros(1,length(E_th)); 99 | for j = 1:length(E_th) 100 | mi = zeros(length(rho1),length(rho2)); 101 | for i = 1:length(rho1) 102 | E1 = 0.5 * pt * (1-rho1(i))* h(1)^2; 103 | if E1 < E_th(j) 104 | break; 105 | end 106 | end 107 | num_rho1 = i-1; 108 | 109 | for i = 1:length(rho2) 110 | E2 = 0.5 * pt * (1-rho2(i))* h(2)^2; 111 | if E2 < E_th(j) 112 | break; 113 | end 114 | end 115 | num_rho2 = i-1; 116 | 117 | for i = 1:num_rho1 118 | for k = 1:num_rho2 119 | mi(i,k) = 1/2*log10(1+rho1(i)^2*rho2(k)^2*P/(rho1(i)^2*pw_noise+rho2(k)^2*pw_noise+pw_noise*pw_noise/P)); 120 | end 121 | end 122 | 123 | mi_2_max (j) = max(max(mi)'); 124 | %mi_diag_35_max(j) = max(diag(mi)); 125 | end 126 | 127 | num_max = sum(mi_max ~= 0); 128 | num_diag_max = sum(mi_diag_max ~= 0); 129 | num_25_max = sum(mi_25_max ~= 0); 130 | num_2_max = sum(mi_2_max ~= 0); 131 | % 132 | plot([E_th(1:num_max),E_th(num_max)], [mi_max(1:num_max),0],'r-*','LineWidth',1); 133 | hold on; 134 | plot(E_th(1:num_diag_max), mi_diag_max(1:num_diag_max),'b-s','LineWidth',1); 135 | hold on; 136 | plot(E_th(1:num_25_max), mi_25_max(1:num_25_max),'k-v','LineWidth',1); 137 | hold on; 138 | plot([E_th(1:num_2_max),E_th(num_2_max)], [mi_2_max(1:num_2_max),0],'k-o','LineWidth',1); 139 | hold on; 140 | % % plot(E_th, mi_diag_max_2,'LineWidth',1.5); 141 | 142 | area1 = area([0,E_th(4)],[mi_max(4),mi_max(4)], 'LineStyle','none'); 143 | plot([0,E_th(4)],[mi_max(4),mi_max(4)],'LineStyle','--','LineWidth',1.5,'Color','#0072BD'); 144 | plot([E_th(4),E_th(4)],[0,mi_max(4)],'LineStyle','--','LineWidth',1.5,'Color','#0072BD'); 145 | 146 | area2 = area([0,E_th(9)],[mi_max(9),mi_max(9)], 'LineStyle','none'); 147 | plot([0,E_th(9)],[mi_max(9),mi_max(9)],'LineStyle','--','LineWidth',1.5,'Color','#77AC30'); 148 | plot([E_th(9),E_th(9)],[0,mi_max(9)],'LineStyle','--','LineWidth',1.5,'Color','#77AC30'); 149 | 150 | area3 = area([0,E_th(12)],[mi_max(12),mi_max(12)], 'LineStyle','none'); 151 | plot([0,E_th(12)],[mi_max(12),mi_max(12)],'LineStyle','--','LineWidth',1.5,'Color','#A2142F'); 152 | plot([E_th(12),E_th(12)],[0,mi_max(12)],'LineStyle','--','LineWidth',1.5,'Color','#A2142F'); 153 | 154 | area1.FaceColor = '#0072BD'; 155 | area2.FaceColor = '#77AC30'; 156 | area3.FaceColor = '#A2142F'; 157 | area1.FaceAlpha = 0.1; 158 | area2.FaceAlpha = 0.1; 159 | area3.FaceAlpha = 0.1; 160 | grid on; 161 | 162 | dim = [0.003/0.0127 0.725/1.05 0.0500 0.0500]; 163 | a1 = annotation('textbox',dim,'String','K1'); 164 | a1.Color = 'red'; 165 | a1.FontSize = 12; 166 | a1.LineStyle = 'none'; 167 | 168 | dim = [0.003/0.0068 0.725/1.476 0.0500 0.0500]; 169 | a2 = annotation('textbox',dim,'String','K2'); 170 | a2.Color = 'red'; 171 | a2.FontSize = 12; 172 | a2.LineStyle = 'none'; 173 | 174 | dim = [0.003/0.0054 0.725/3.1 0.0500 0.0500]; 175 | a3 = annotation('textbox',dim,'String','K3'); 176 | a3.Color = 'red'; 177 | a3.FontSize = 12; 178 | a3.LineStyle = 'none'; 179 | 180 | 181 | axis([0 0.02 0 1.05]); 182 | ylabel('每比特互信息(bits)','Fontname','<宋体>'); 183 | xlabel('能量收集门限','Fontname','<宋体>'); 184 | legend('信号功率 = 1, 噪声功率 =0.001','信号功率 = 1, 噪声功率 =0.001 (\rho_1 = \rho_2)','信号功率 = 1, 噪声功率 =0.003','信号功率 = 1.5, 噪声功率 =0.001','Fontname','<宋体>') 185 | 186 | %mesh(rho1,rho2,mi); 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /sim08/ray_model.m: -------------------------------------------------------------------------------- 1 | function h = ray_model(d,taps) 2 | % generate the exponential rayleigh model 3 | % inputs: 4 | % d: the distance between two objects 5 | % taps: the delay taps 6 | % output: 7 | % h: the exponential Rayleigh model 8 | 9 | lamda = 3; 10 | 11 | h_cg = 5*d^(-lamda/2); 12 | 13 | pow_h = exp(-(0:taps-1)); 14 | pow_h = h_cg*pow_h/norm(pow_h); 15 | 16 | h = (randn(1,1) + 1i*randn(1,1)) * sqrt(pow_h); -------------------------------------------------------------------------------- /sim08/ray_model_cor.m: -------------------------------------------------------------------------------- 1 | function h = ray_model_cor(h_b,cor,d) 2 | % generate a exponential rayleigh model that is correlated to other 3 | % Raymodel 4 | % inputs: 5 | % d: the distance between two objects 6 | % cor: correlation coefficient 7 | % h_b: the base Rayleigh channel model 8 | % output: 9 | % h: the exponential Rayleigh model correlated to channel h 10 | lamda = 3; 11 | 12 | h_cg = 5*d^(-lamda/2); 13 | 14 | pow_h = exp(-(0:length(h_b)-1)); 15 | pow_h = h_cg*pow_h/norm(pow_h); 16 | 17 | h = cor*h_b + sqrt(1-cor^2).*sqrt(pow_h).* (randn(1,length(h_b)) + 1i*randn(1,length(h_b))); -------------------------------------------------------------------------------- /sim08/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangpu03/physical-key-generation/5244028d6634e612f221823e3c1b653b6df1734a/sim08/readme.md -------------------------------------------------------------------------------- /sim08/receiver_design.m: -------------------------------------------------------------------------------- 1 | function [y,y_cp] = receiver_design(y_d, y_b, n_ofdm, n_cp, n_frame, n_L) 2 | % combinaiton of two signals 3 | 4 | sym_rem = mod(n_ofdm-mod(length(y_d),n_ofdm),n_ofdm); 5 | padding = repmat(0+0i,sym_rem,1); 6 | y_d_padded = [y_d;padding]; 7 | 8 | sym_rem = mod(n_ofdm-mod(length(y_b),n_ofdm),n_ofdm); 9 | padding = repmat(0+0i,sym_rem,1); 10 | y_b_padded = [y_b;padding]; 11 | 12 | y = y_d_padded+y_b_padded; 13 | 14 | % calculate the desired information at receivering devices 15 | n_fft = n_ofdm - n_cp; 16 | zb = y(n_L:n_cp) - y(n_fft+n_L:n_fft+n_cp); 17 | for n = 1:1:n_frame-1 18 | zb =[zb(:); (y(n*n_ofdm+n_L:n*n_ofdm+n_cp)-y(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 19 | end 20 | 21 | zd = y(n_L:n_cp) + y(n_fft+n_L:n_fft+n_cp); 22 | for n = 1:1:n_frame-1 23 | zd =[zd(:); (y(n*n_ofdm+n_L:n*n_ofdm+n_cp)+y(n*n_ofdm+n_fft+n_L:n*n_ofdm+n_fft+n_cp))]; 24 | end 25 | y_cp = zb .* zd; 26 | -------------------------------------------------------------------------------- /sim08/receiver_design2.m: -------------------------------------------------------------------------------- 1 | function [y_cp] = receiver_design2(y, n_ofdm, n_cp, n_frame, n_L) 2 | 3 | % calculate the desired information at receivering devices 4 | y_cp = y(n_L:n_cp); 5 | for n = 1:1:n_frame-1 6 | y_cp =[y_cp(:); (y(n*n_ofdm+n_L:n*n_ofdm+n_cp))]; 7 | end 8 | -------------------------------------------------------------------------------- /sim08/skr_snr.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = skr_snr(data_ofdm, n_ofdm, n_cp ,n_frame, cor, d_e1, snr) 2 | 3 | pt = 10^(-2); 4 | %snr = 100; 5 | alpha = 0.3 + 1i*0.4; 6 | pw_noise = pt/10^(snr/10); 7 | 8 | d = [8, 7, 3]; 9 | taps = [8, 7, 3]; 10 | n_L = max(taps(1),taps(2))+taps(3)-1; 11 | 12 | h1 = ray_model(d(1),taps(1)); 13 | h2 = ray_model(d(2),taps(2)); 14 | 15 | h_12 = ray_model(d(3),taps(3)); 16 | h_21 = h_12; 17 | 18 | cor_h1_he = cor; 19 | cor_h12_he2 = cor; 20 | 21 | % assume Eve locate closer to device 1 22 | %cor = 0; 23 | he = eave_ray_model(h1,cor_h1_he,d(1)); 24 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 25 | 26 | %d_e1 = 1; 27 | tap_e1 = 1; 28 | h_e1 = ray_model(d_e1,tap_e1); 29 | 30 | % all transmissions in ambient backscatter communication 31 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 32 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 33 | 34 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 35 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 36 | 37 | y1_b = ofdm_trans(back2, h_12, pw_noise); 38 | y2_b = ofdm_trans(back1, h_12, pw_noise); 39 | 40 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 41 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 42 | 43 | v_y1_cp = mean(abs(y1_cp)); 44 | v_y2_cp = mean(abs(y2_cp)); 45 | 46 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 47 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 48 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 49 | 50 | 51 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 52 | v_ye1_cp = mean(abs(ye1_cp)); 53 | v_ye2_cp = mean(abs(ye2_cp)); 54 | -------------------------------------------------------------------------------- /sim08/skr_snr_50000.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangpu03/physical-key-generation/5244028d6634e612f221823e3c1b653b6df1734a/sim08/skr_snr_50000.mat -------------------------------------------------------------------------------- /sim08/skr_snr_trad.m: -------------------------------------------------------------------------------- 1 | function [v_y1_cp, v_y2_cp, v_ye1_cp, v_ye2_cp] = skr_snr_trad(data_ofdm, n_ofdm, n_cp ,n_frame, cor, d_e1, snr) 2 | 3 | pt = 10^(-2); 4 | %snr = 100; 5 | alpha = 0.3 + 1i*0.4; 6 | pw_noise = pt/10^(snr/10); 7 | 8 | d = [8, 7, 3]; 9 | taps = [8, 7, 3]; 10 | n_L = max(taps(1),taps(2))+taps(3)-1; 11 | 12 | h1 = ray_model(d(1),taps(1)); 13 | h2 = ray_model(d(2),taps(2)); 14 | 15 | h_12 = ray_model(d(3),taps(3)); 16 | h_21 = h_12; 17 | 18 | % 假设h1信道和h3信道一摸一样,只考虑两个设备之间的信道,将其作为窃听信道 19 | cor_h1_he = 1; 20 | cor_h12_he2 = cor; 21 | 22 | % assume Eve locate closer to device 1 23 | %cor = 0; 24 | he = eave_ray_model(h1,cor_h1_he,d(1)); 25 | h_e2 = eave_ray_model(h_12,cor_h12_he2,d(3)); 26 | 27 | %d_e1 = 1; 28 | tap_e1 = 1; 29 | h_e1 = ray_model(d_e1,tap_e1); 30 | 31 | % all transmissions in ambient backscatter communication 32 | y1_d = ofdm_trans(data_ofdm, h1, pw_noise); 33 | back1 = ofdm_back(y1_d, alpha, n_ofdm, n_frame); 34 | 35 | y2_d = ofdm_trans(data_ofdm, h2, pw_noise); 36 | back2 = ofdm_back(y2_d, alpha, n_ofdm, n_frame); 37 | 38 | y1_b = ofdm_trans(back2, h_12, pw_noise); 39 | y2_b = ofdm_trans(back1, h_12, pw_noise); 40 | 41 | [y1,y1_cp] = receiver_design(y1_d, y1_b, n_ofdm, n_cp, n_frame, n_L); 42 | [y2,y2_cp] = receiver_design(y2_d, y2_b, n_ofdm, n_cp, n_frame, n_L); 43 | 44 | v_y1_cp = mean(abs(y1_cp)); 45 | v_y2_cp = mean(abs(y2_cp)); 46 | 47 | ye_d = ofdm_trans(data_ofdm, he, pw_noise); 48 | y_b_e2 = ofdm_trans(back2, h_e2, pw_noise); 49 | y_b_e1 = ofdm_trans(back1, h_e1, pw_noise); 50 | 51 | [ye1_cp, ye2_cp] = evea_design(ye_d,y_b_e1, y_b_e2, n_ofdm, n_cp, n_frame, n_L); 52 | v_ye1_cp = mean(abs(ye1_cp)); 53 | v_ye2_cp = mean(abs(ye2_cp)); 54 | -------------------------------------------------------------------------------- /sim08/test_corr.m: -------------------------------------------------------------------------------- 1 | clc; 2 | clear; 3 | h_ab = randn(1,5000) + 1i*randn(1,5000); 4 | r2_d = 0.9; 5 | h_ae = r2_d*h_ab + sqrt(1-r2_d^2)*(randn(1,5000) + 1i*randn(1,5000)); 6 | cor = corrcoef(h_ab,h_ae) 7 | cor_abs = corrcoef(abs(h_ab),abs(h_ae)) 8 | 9 | exp_PDP = exp(-(0:10-1)); 10 | exp_PDP = exp_PDP/norm(exp_PDP); 11 | 12 | h_ab_ofdm=(randn(5000,1)+1i*randn(5000,1))*sqrt(exp_PDP/2); 13 | 14 | h_ae_ofdm = zeros(5000,10); 15 | for i = 1:length(exp_PDP) 16 | h_ae_ofdm(:,i) = r2_d*h_ab_ofdm(:,i) + sqrt(exp_PDP(i)/2)*sqrt(1-r2_d^2)*(randn(5000,1) + 1i*randn(5000,1)); 17 | end 18 | 19 | cor_ofdm = corrcoef(h_ab_ofdm,h_ae_ofdm) 20 | 21 | 22 | % h_ae_ofdm2 = zeros(5000,10); 23 | % h_ae_ofdm2 = r2_d*h_ab_ofdm .+ sqrt(1-r2_d^2)*randn(1,1) + 1i*randn(1,1) 24 | 25 | --------------------------------------------------------------------------------