diff --git a/1sem/octave/06/main.m b/1sem/octave/06/main.m new file mode 100644 index 0000000..7ad2498 --- /dev/null +++ b/1sem/octave/06/main.m @@ -0,0 +1,21 @@ +#stage 4 +V=33; +rand("state", V); + +#stage 5, 6, 7 +fid = fopen("results.txt", "w+"); +origs = -1000 + 2000*rand(1, 100); +abserrs = []; +for i = 1:100 + x = origs(i); + binf = print_num_bin(x, 4); + decf = read_num_bin(binf); + abserr = abs(x - decf); + abserrs(end + 1) = abserr; + fprintf(fid, "%.6f %s %.6f %.6f\n", x, binf, decf, abserr); +end +fclose(fid); + +#stage 8 +stats = [min(abserrs), mean(abserrs), max(abserrs)]; +save -ascii "stats.txt" stats; diff --git a/1sem/octave/06/print_num_bin.m b/1sem/octave/06/print_num_bin.m new file mode 100644 index 0000000..65f2e0d --- /dev/null +++ b/1sem/octave/06/print_num_bin.m @@ -0,0 +1,13 @@ +function s = print_num_bin(n, prec) + neg = n < 0; + n = abs(n); + v = 2^prec; + n = round(n * v); + s = dec2bin(n); + s = [s(1:length(s)-prec) "." s(length(s)-prec+1:end)]; + dp = strfind(s, "."); + s = [s(1:dp) s(dp+1:dp+prec)]; + if neg + s = ["-" s]; + end +end diff --git a/1sem/octave/06/read_num_bin.m b/1sem/octave/06/read_num_bin.m new file mode 100644 index 0000000..4fb2f76 --- /dev/null +++ b/1sem/octave/06/read_num_bin.m @@ -0,0 +1,18 @@ +function n = read_num_bin(s) + neg = s(1) == "-"; + if neg + s = substr(s, 2); + end + ind = find(s == '.'); + decpart = s(1:ind-1); + floatpart = s(ind+1:end); + n = bin2dec(decpart); + for d = 1:length(floatpart) + if floatpart(d) == '1' + n = n + 2^(-d); + end + end + if neg + n = -n; + end +end diff --git a/1sem/octave/06/results.txt b/1sem/octave/06/results.txt new file mode 100644 index 0000000..d222520 --- /dev/null +++ b/1sem/octave/06/results.txt @@ -0,0 +1,101 @@ +140.656846 10001100.1011 140.687500 0.030654 +264.465991 100001000.0111 264.437500 0.028491 +634.007720 1001111010.0 634.000000 0.007720 +20 +-445.418291 -110111101.0111 -445.437500 0.019209 +303.719936 100101111.1100 303.750000 0.030064 +781.621911 1100001101.1010 781.625000 0.003089 +817.657046 1100110001.1011 817.687500 0.030454 +-626.974881 -1001110011.0000 -627.000000 0.025119 +303.454219 100101111.0111 303.437500 0.016719 +234.234556 11101010.0100 234.250000 0.015444 +6.787677 110.1101 6.812500 0.024823 +932.395930 1110100100.0110 932.375000 0.020930 +56.532450 111000.1001 56.562500 0.030050 +-109.491806 -1101101.1000 -109.500000 0.008194 +887.122313 1101110111.0010 887.125000 0.002687 +271.239654 100001111.0100 271.250000 0.010346 +-397.411087 -110001101.0111 -397.437500 0.026413 +-381.481163 -101111101.1000 -381.500000 0.018837 +-7.798867 -111.1101 -7.812500 0.013633 +-894.803915 -1101111110.1101 -894.812500 0.008585 +215.163393 11010111.0011 215.187500 0.024107 +471.709217 111010111.1011 471.687500 0.021717 +-147.716376 -10010011.1011 -147.687500 0.028876 +693.175737 1010110101.0011 693.187500 0.011763 +855.969091 1101011000.0000 856.000000 0.030909 +111.215946 1101111.0011 111.187500 0.028446 +362.705205 101101010.1011 362.687500 0.017705 +-765.485378 -1011111101.1000 -765.500000 0.014622 +-887.960891 -1101110111.1111 -887.937500 0.023391 +960.044844 1111000000.0001 960.062500 0.017656 +-431.119785 -110101111.0010 -431.125000 0.005215 +-573.274583 -1000111101.0100 -573.250000 0.024583 +793.322668 1100011001.0101 793.312500 0.010168 +499.638280 111110011.1010 499.625000 0.013280 +-753.634264 -1011110001.1010 -753.625000 0.009264 +-356.657717 -101100100.1011 -356.687500 0.029783 +-514.643542 -1000000010.1010 -514.625000 0.018542 +-454.588140 -111000110.1001 -454.562500 0.025640 +-987.254227 -1111011011.0100 -987.250000 0.004227 +49.367274 110001.0110 49.375000 0.007726 +-391.314796 -110000111.0101 -391.312500 0.002296 +-211.581165 -11010011.1001 -211.562500 0.018665 +-629.127686 -1001110101.0010 -629.125000 0.002686 +-779.830219 -1100001011.1101 -779.812500 0.017719 +-934.170732 -1110100110.0011 -934.187500 0.016768 +745.510871 1011101001.1000 745.500000 0.010871 +494.739304 111101110.1100 494.750000 0.010696 +119.303880 1110111.0101 119.312500 0.008620 +-752.316236 -1011110000.0101 -752.312500 0.003736 +-702.100767 -1010111110.0010 -702.125000 0.024233 +-760.694477 -1011111000.1011 -760.687500 0.006977 +-366.894409 -101101110.1110 -366.875000 0.019409 +-884.805822 -1101110100.1101 -884.812500 0.006678 +-449.191431 -111000001.0011 -449.187500 0.003931 +-594.210478 -1001010010.0011 -594.187500 0.022978 +-614.323248 -1001100110.0101 -614.312500 0.010748 +307.457721 100110011.0111 307.437500 0.020221 +-84.401032 -1010100.0110 -84.375000 0.026032 +-53.039465 -110101.0001 -53.062500 0.023035 +-283.877647 -100011011.1110 -283.875000 0.002647 +78.027926 1001110.0000 78.000000 0.027926 +570.322422 1000111010.0101 570.312500 0.009922 +-383.986853 -110000000.0000 -384.000000 0.013147 +-859.546631 -1101011011.1001 -859.562500 0.015869 +-37.657807 -100101.1011 -37.687500 0.029693 +-241.662089 -11110001.1011 -241.687500 0.025411 +561.012005 1000110001.0000 561.000000 0.012005 +-778.016393 -1100001010.0000 -778.000000 0.016393 +745.455954 1011101001.0111 745.437500 0.018454 +-970.346139 -1111001010.0110 -970.375000 0.028861 +84.473262 1010100.1000 84.500000 0.026738 +-112.805192 -1110000.1101 -112.812500 0.007308 +-369.337769 -101110001.0101 -369.312500 0.025269 +777.801631 1100001001.1101 777.812500 0.010869 +404.201774 110010100.0011 404.187500 0.014274 +-673.577310 -1010100001.1001 -673.562500 0.014810 +-10.120724 -1010.0010 -10.125000 0.004276 +224.525414 11100000.1000 224.500000 0.025414 +-932.991479 -1110100101.0000 -933.000000 0.008521 +-825.066717 -1100111001.0001 -825.062500 0.004217 +203.474744 11001011.1000 203.500000 0.025256 +459.012915 111001011.0000 459.000000 0.012915 +-74.621956 -1001010.1010 -74.625000 0.003044 +-155.875222 -10011011.1110 -155.875000 0.000222 +13.890809 1101.1110 13.875000 0.015809 +-478.827514 -111011110.1101 -478.812500 0.015014 +752.983773 1011110001.0000 753.000000 0.016227.000650 +-958.935130 -1110111110.1111 -958.937500 0.002370 +-205.781515 -11001101.1101 -205.812500 0.030985 +606.098294 1001011110.001 606.125000 0.026706 +-350.091142 -101011110.0001 -350.062500 0.028642 +-788.869426 -1100010100.111 -788.875000 0.005574 +-629.474760 -1001110101.1 -629.500000 0.025240 +423.349877 110100111.011 423.375000 0.025123 +244.037508 11110100.0001 244.062500 0.024992 +-427.668975 -110101011.1011 -427.687500 0.018525 +247.149172 11110111.001 247.125000 0.024172 +521.321129 1000001001.0101 521.312500 0.008629 +47.149172 11110111.0010 247.125000 0.024172 +521.321129 1000001001.0101 521.312500 0.008629 diff --git a/1sem/octave/06/stats.txt b/1sem/octave/06/stats.txt new file mode 100644 index 0000000..a46ee97 --- /dev/null +++ b/1sem/octave/06/stats.txt @@ -0,0 +1 @@ + 2.21687316e-04 1.65226217e-02 3.09853200e-02 diff --git a/1sem/octave/08/alph_entropy.m b/1sem/octave/08/alph_entropy.m new file mode 100644 index 0000000..be9de2a --- /dev/null +++ b/1sem/octave/08/alph_entropy.m @@ -0,0 +1,4 @@ +function [h] = alph_entropy(P); + P = P(P ~= 0); + h = -sum(P.*log2(P)); +endfunction; diff --git a/1sem/octave/08/avg_len.m b/1sem/octave/08/avg_len.m new file mode 100644 index 0000000..fba29b8 --- /dev/null +++ b/1sem/octave/08/avg_len.m @@ -0,0 +1,6 @@ +## Author: nuark +## Created: 2019-12-08 + +function l = avg_len(C, P) + l = sum(cellfun(@length, C) .* P); +endfunction diff --git a/1sem/octave/08/code.txt b/1sem/octave/08/code.txt new file mode 100644 index 0000000..26e6de7 --- /dev/null +++ b/1sem/octave/08/code.txt @@ -0,0 +1,16 @@ +0000 +0001 +0010 +0011 +0100 +0101 +0110 +0111 +1000 +1001 +1010 +1011 +1100 +1101 +1110 +1111 diff --git a/1sem/octave/08/decode_msg.m b/1sem/octave/08/decode_msg.m new file mode 100644 index 0000000..d4dacc0 --- /dev/null +++ b/1sem/octave/08/decode_msg.m @@ -0,0 +1,17 @@ +## Author: nuark +## Created: 2019-12-08 + +function msg = decode_msg(emsg, code) + alph = ['0':'9' 'A':'F']; + msg = ''; + word = ''; + + for c = emsg + word(end + 1) = c; + match = strcmp(code, word); + if any(match) + msg = strcat(msg, alph(match)); + word = ''; + end + end +end diff --git a/1sem/octave/08/encode_msg.m b/1sem/octave/08/encode_msg.m new file mode 100644 index 0000000..abe0eb1 --- /dev/null +++ b/1sem/octave/08/encode_msg.m @@ -0,0 +1,18 @@ +## Author: nuark +## Created: 2019-12-08 + +function emsg = encode_msg(msg, code) + alph = ['0':'9' 'A':'F']; + l_msg = length(msg); + + emsg = ''; + for i = 1:l_msg + mask = alph == msg(i); + if any(mask) + emsg = strcat(emsg, code(mask)); + else + warning("[WARN] Symbol '%s' (at pos. %d from msg) not found in alphabet", msg(i), i) + end + end + emsg = emsg{1,1}; +end diff --git a/1sem/octave/08/gen_msg.m b/1sem/octave/08/gen_msg.m new file mode 100644 index 0000000..36cefb1 --- /dev/null +++ b/1sem/octave/08/gen_msg.m @@ -0,0 +1,49 @@ +% Программа генерации случайного сообщения в алфавите, содержащем не более 36 символов: 0, ..., 9, A, ..., Z. +% Автор: Кирилл Владимирович Пушкарёв. +% Дата: 26 октября 2019 г. +% Версия: 0.2 +% Параметры: +% p - вектор, содержащий от 2 до 36 неотрицательных чисел. +% Вероятности символов алфавита. +% len - целое число. +% Длина сообщения. +function msg = gen_msg(p, len) + % Создаём вектор символов алфавита 0, ..., 9, A, ..., Z + alph = ['0':'9' 'A':'Z']; + % Если p не вектор, ошибка + if ~isvector(p) + error('p must be a vector') + end + % Если длина вектора p больше длины alph, ошибка + if length(p) > length(alph) + % Выводим сообщение об ошибке, подставляя в него целые числа (%d) — длины векторов + error('p is too long (%d > %d)', length(p), length(alph)); + end + % Если длина вектора p меньше 2, ошибка + if length(p) < 2 + error('p is too short (%d < 2)', length(p)); + end + % Если длина не одно число, ошибка + if ~isscalar(len) + error('len must be a scalar') + end + % Если длина меньше 1, ошибка + if len < 1 + error('len is too small (%d < 1)', len) + end + % Создаём пустую строку для записи сообщения + msg = ''; + % Цикл по i от 1 до len + for i = 1:len + % Заносим случайно выбранный с заданными вероятностями символ в msg + msg(i) = alph(rand_discr(p)); + end +end + +% Функция генерации целого случайного числа i с вероятностью p(i). +% Параметры: +% p - вектор неотрицательных чисел, сумма элементов которого равна 1. +% Вероятности. +function r = rand_discr(p) + r = sum(cumsum(p) < rand()) + 1; +end diff --git a/1sem/octave/08/hex.txt b/1sem/octave/08/hex.txt new file mode 100644 index 0000000..3009b0c --- /dev/null +++ b/1sem/octave/08/hex.txt @@ -0,0 +1 @@ + 4.80000000e+01 4.90000000e+01 5.00000000e+01 5.10000000e+01 5.20000000e+01 5.30000000e+01 5.40000000e+01 5.50000000e+01 5.60000000e+01 5.70000000e+01 6.50000000e+01 6.60000000e+01 6.70000000e+01 6.80000000e+01 6.90000000e+01 7.00000000e+01 diff --git a/1sem/octave/08/main.m b/1sem/octave/08/main.m new file mode 100644 index 0000000..8b7e587 --- /dev/null +++ b/1sem/octave/08/main.m @@ -0,0 +1,31 @@ +#stage 6 +V=33; +rand("state", V); + +#stage 7 +alph = char([48:57 65:70]); +save -ascii "hex.txt" alph; + +#stage 8 +code = arrayfun(@(n)dec2bin(n, 4), 0:15, "UniformOutput", false); +dlmwrite('code.txt', char(code), ''); + +#stage 9 +r = rand(1, 16); +ralph = r./sum(r); +for i = 1:100 + msg = gen_msg(ralph, 10); + encoded = encode_msg(msg, code); + decoded = decode_msg(encoded, code); + if ~strcmp(msg, decoded) + error("[ERR] Encoded message '%s' not equal to decoded variant '%s'!", msg, decoded) + end +end + +a_len = avg_len(code, ralph); +min_avg_len = min_bits(length(alph)); +min_len = min(arrayfun(@length, code)); +rel_opt = alph_entropy(ralph)/(log2(length(ralph)) * a_len); +results = [a_len, min_avg_len, min_len, rel_opt]; + +save -ascii "results.txt" results; \ No newline at end of file diff --git a/1sem/octave/08/min_bits.m b/1sem/octave/08/min_bits.m new file mode 100644 index 0000000..c20efae --- /dev/null +++ b/1sem/octave/08/min_bits.m @@ -0,0 +1,6 @@ +## Author: nuark +## Created: 2019-12-08 + +function r = min_bits(N) + r = ceil(log2(N)); +endfunction diff --git a/1sem/octave/08/results.txt b/1sem/octave/08/results.txt new file mode 100644 index 0000000..86083e2 --- /dev/null +++ b/1sem/octave/08/results.txt @@ -0,0 +1 @@ + 4.00000000e+00 4.00000000e+00 1.00000000e+00 2.44102196e-01