1 ## Copyright (C) 2003 David Bateman
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} {} comms ('help')
18 ## @deftypefnx {Function File} {} comms ('info')
19 ## @deftypefnx {Function File} {} comms ('info', @var{mod})
20 ## @deftypefnx {Function File} {} comms ('test')
21 ## @deftypefnx {Function File} {} comms ('test', @var{mod})
23 ## Manual and test code for the Octave Communications toolbox. There are
24 ## 5 possible ways to call this function.
27 ## @item comms ('help')
28 ## Display this help message. Called with no arguments, this function also
29 ## displays this help message
30 ## @item comms ('info')
31 ## Open the Commumications toolbox manual
32 ## @item comms ('info', @var{mod})
33 ## Open the Commumications toolbox manual at the section specified by
35 ## @item comms ('test')
36 ## Run all of the test code for the Communications toolbox.
37 ## @item comms ('test', @var{mod})
38 ## Run only the test code for the Communications toolbox in the module
42 ## Valid values for the varibale @var{mod} are
48 ## The random signal generation and analysis package
50 ## The source coding functions of the package
52 ## The block coding functions
54 ## The convolution coding package
56 ## The modulation package
58 ## The special filter functions
60 ## The Galois fields package
63 ## Please note that this function file should be used as an example of the
64 ## use of this toolbox.
67 function retval = comms(typ, tests)
76 if strcmp(tests,"all")
78 elseif strcmp(tests,"random")
79 nodename = "Random Signals";
80 elseif strcmp(tests,"source")
81 nodename = "Source Coding";
82 elseif strcmp(tests,"block")
83 nodename = "Block Coding";
84 elseif strcmp(tests,"convol")
85 nodename = "Convolutional Coding";
86 elseif strcmp(tests,"modulation")
87 nodename = "Modulations";
88 elseif strcmp(tests,"special")
89 nodename = "Special Fields";
90 elseif strcmp(tests,"galois")
91 nodename = "Galois Fields";
93 error ("comms: unrecognized package");
96 if (strcmp(typ,"help"))
98 elseif (strcmp(typ,"info"))
100 if (!isempty(char(strsplit (path, ":"))))
101 infopaths =[infopaths; char(strsplit (path, ":"))];
103 if (!isempty(char(strsplit (DEFAULT_LOADPATH, ":"))))
104 infopaths =[infopaths; char(strsplit (DEFAULT_LOADPATH, ":"))];
106 for i=1:size(infopaths,1)
107 infopath = deblank(infopaths(i,:));
108 len = length(infopath);
110 if (len > 1 && strcmp(infopath([len-1, len]),"//"))
111 [status, showfile] = system(["find '", infopath(1:len-1), ...
112 "' -name ", infofile]);
114 [status, showfile] = system(["find '", infopath, "' -name ", ...
115 infofile, " -maxdepth 1"]);
117 if (length(showfile))
122 if (!exist("showfile") || !length(showfile))
123 error("comms: info file not found");
125 if (showfile(length(showfile)) == "\n")
126 showfile = showfile(1:length(showfile)-1);
129 if (exist("INFO_PROGAM"))
130 [testret, testout] = system(["'", INFO_PROGRAM, "' --version"]);
132 error("comms: info command not found");
134 system(["'", INFO_PROGRAM, "' --file '", showfile, "' --node '", ...
138 [testret, testout] = system("info --version");
140 error("comms: info command not found");
142 system(["info --file '", showfile, "' --node '", nodename, "'"]);
145 elseif (strcmp(typ,"test"))
146 pso = page_screen_output();
148 page_screen_output(0);
150 if (strcmp(tests,"random") || strcmp(tests,"all"))
151 fprintf("\n<< Random Signals Package >>\n");
152 fprintf(" Signal Creation: ");
156 if (any(size(x) != [10, 10]) || (max(x(:)) >= m) || (min(x(:) < 0)))
159 x = randsrc(n,n,[1, 1i, -1, -1i,]);
160 if (any(size(x) != [10, 10]) || ...
161 !all(all((x == 1) | (x == 1i) | (x == -1) | (x == -1i))))
165 if (any(size(x) != [10, 10]) || any(sum(x') != ones(1,n)))
169 nse_30dBm_1Ohm = wgn(10000,1,30,1,"dBm");
170 nse_0dBW_1Ohm = wgn(10000,1,0,1,"dBW");
171 nse_1W_1Ohm = wgn(10000,1,1,1,"linear");
172 ## Standard deviations should be about 1... If it is greater than
173 ## some value flag an error
174 dev = [std(nse_30dBm_1Ohm), std(nse_0dBW_1Ohm), std(nse_1W_1Ohm)];
181 noisy = awgn(y, 10, "dB", "measured");
182 if (any(size(y) != size(noisy)))
185 ## This is a pretty arbitrary test, but should pick up gross errors
186 if (any(abs(y-noisy) > 1))
191 fprintf(" Signal Analysis: ");
192 ## Protect!! Since bitxor might not be installed
196 msg = randint(n,n,2^m);
197 noisy = bitxor(msg,diag(3*ones(1,n)));
198 [berr, brate] = biterr(msg, noisy, m);
199 if ((berr != 2*n) || (brate != 2/(n*m)))
202 [serr, srate] = symerr(msg, noisy);
203 if ((serr != n) || (srate != 1/n))
208 ## Can not easily test eyediagram, scatterplot!!
211 if (strcmp(tests,"source") || strcmp(tests,"all"))
212 fprintf("\n<< Source Coding Package >>\n");
213 fprintf(" PCM Functions: ");
214 fprintf("Not tested\n");
215 fprintf(" Quantization Functions: ");
218 [tab, cod] = lloyds(y, 16);
219 [i, q, d] = quantiz(y, tab, cod);
226 x = sin([0:0.1:2*pi]);
227 y = compand(x, mu, V, "mu/compressor");
228 z = compand(x, mu, V, "mu/expander");
229 ## Again this is a pretty arbitrary test
230 if (max(abs(x-z)) > 0.1)
235 if (strcmp(tests,"block") || strcmp(tests,"all"))
236 fprintf("\n<< Block Coding Package >>\n");
237 fprintf(" Cyclic Coding: ");
240 n = 2^m-1; # [15,11] Hamming code
243 if (bi2de(p) != primpoly(m,"nodisplay"))
246 [par, gen] = cyclgen(n,p);
247 if (any(any(gen2par(par) != gen)))
250 if (gfweight(gen) != 3)
254 msg = randint(nsym,k);
255 code = encode(msg,n,k,"cyclic");
256 noisy = mod(code + randerr(nsym,n), 2);
257 dec = decode(noisy,n,k,"cyclic");
258 if (any(any(dec != msg)))
261 try # Protect! If bitshift isn't install!!
262 msg = randint(nsym,1,n);
263 code = encode(msg,n,k,"cyclic/decimal");
264 noisy = mod(code + bitshift(1,randint(nsym,1,n)), n+1);
265 dec = decode(noisy,n,k,"cyclic/decimal");
273 fprintf(" Hamming Coding: ");
276 [par, gen, n, k] = hammgen (m);
277 if (any(any(gen2par(par) != gen)))
280 if (gfweight(gen) != 3)
283 msg = randint(nsym,k);
284 code = encode(msg,n,k,"hamming");
285 noisy = mod(code + randerr(nsym,n), 2);
286 dec = decode(noisy,n,k,"hamming");
287 if (any(any(dec != msg)))
290 try # Protect! If bitshift isn't install!!
291 msg = randint(nsym,1,n);
292 code = encode(msg,n,k,"hamming/decimal");
293 noisy = mod(code + bitshift(1,randint(nsym,1,n)), n+1);
294 dec = decode(noisy,n,k,"hamming/decimal");
302 fprintf(" BCH Coding: ");
306 p = bchpoly(2^m - 1);
307 ## Pick a BCH code from the list at random
308 l = ceil(size(p,1) * rand(1,1));
312 ## Symbols represented by rows of binary matrix
313 msg = randint(nsym,k);
314 code = encode(msg,n,k,"bch");
315 noisy = mod(code + randerr(nsym,n), 2);
316 dec = decode(noisy,n,k,"bch");
317 if (any(any(dec != msg)))
320 try # Protect! If bitshift isn't install!!
321 msg = randint(nsym,1,n);
322 code = encode(msg,n,k,"bch/decimal");
323 noisy = mod(code + bitshift(1,randint(nsym,1,n)), n+1);
324 dec = decode(noisy,n,k,"bch/decimal");
332 fprintf(" Reed-Solomon Coding: ");
333 ## Test for a CCSDS like coder, but without dual-basis translation
341 ## CCSDS generator polynomial
342 ggrs = rsgenpoly(nrs, krs, prs, fcr, step);
345 msg = gf(floor(2^mrs*rand(2,krs)),mrs,prs);
346 cde = rsenc(msg,nrs,krs,ggrs);
349 noisy = cde + [ 255,0,255,0,255,zeros(1,250); ...
350 0,255,0,255,zeros(1,251)];
352 ## Decode (better to pass fcr and step rather than gg for speed)
353 dec = rsdec(noisy,nrs,krs,fcr,step);
360 if (strcmp(tests,"convol") || strcmp(tests,"all"))
361 fprintf("\n<< Convolutional Coding Package >>\n");
362 fprintf(" Utility functions: ");
363 ## create a trellis, use poly2trellis and test with istrellis
364 fprintf("Not tested\n");
365 fprintf(" Coding: ");
366 ## use convenc, punturing??
367 fprintf("Not tested\n");
368 fprintf(" Viterbi: ");
370 fprintf("Not tested\n");
372 if (strcmp(tests,"modulation") || strcmp(tests,"all"))
373 fprintf("\n<< Modulation Package >>\n");
374 fprintf(" Analog Modulation: ");
378 xq = x + 1i * cos(2*pi*t);
379 ## Can not test FM as it doesn't work !!!
380 if ((max(abs(x - ademodce(amodce(x,Fs,"pm"),Fs,"pm"))) > 0.001) || ...
381 (max(abs(x - ademodce(amodce(x,Fs,"am"),Fs,"am"))) > 0.001) || ...
382 (max(abs(xq - ademodce(amodce(xq,Fs,"qam"),Fs,"qam/cmplx"))) > 0.001))
386 fprintf(" Digital Mapping: ");
390 if ((x != demodmap(modmap(x,1,1,"ask",m),1,1,"ask",m)) || ...
391 (x != demodmap(modmap(x,1,1,"fsk",m),1,1,"fsk",m)) || ...
392 (x != demodmap(modmap(x,1,1,"msk"),1,1,"msk")) || ...
393 (x != demodmap(modmap(x,1,1,"psk",m),1,1,"psk",m)) || ...
394 (x != demodmap(modmap(x,1,1,"qask",m),1,1,"qask",m)) || ...
395 (x != demodmap(modmap(x,1,1,"qask/cir", ...
396 [floor(m/2), m - floor(m/2)]),1,1,"qask/cir", ...
397 [floor(m/2), m - floor(m/2)])))
401 fprintf(" Digital Modulation: ");
402 fprintf("Not tested\n");
404 if (strcmp(tests,"special") || strcmp(tests,"all"))
405 fprintf("\n<< Special Filters Package >>\n");
406 fprintf(" Hankel/Hilbert: ");
407 ## use hank2sys, hilbiir
408 fprintf("Not tested\n");
409 fprintf(" Raised Cosine: ");
410 ## use rcosflt, rcosiir rcosine, rcosfir
411 fprintf("Not tested\n");
413 if (strcmp(tests,"galois") || strcmp(tests,"all"))
414 fprintf("\n<< Galois Fields Package >>\n");
415 ## Testing of the Galois Fields package
416 m = 3; ## must be greater than 2
418 fprintf(" Find primitive polynomials: ");
419 prims = primpoly(m,"all","nodisplay");
421 if (find(prims == i))
423 error("Error in primitive polynomials");
427 error("Error in primitive polynomials");
432 fprintf(" Create Galois variables: ");
440 matlen = ceil(sqrt(2^m));
441 gmat = gf(reshape(mod([0:matlen*matlen-1],2^m),matlen,matlen),m);
443 fprintf(" Access Galois structures: ");
444 if (gcol.m != m || gcol.prim_poly != primpoly(m,"min", ...
449 fprintf(" Miscellaneous functions: ");
450 if (size(gmat) != [matlen, matlen])
453 if (length(grow) != 2^m)
456 if (!any(grow) || all(grow) || any(gzero) || !all(gone))
459 if (isempty(gone) || !isempty(gempty))
463 if (size(tmp,1) != 2^m || size(tmp,2) != 2^m)
468 if ((i == j) && (tmp(i,j) != grow(i)))
470 elseif ((i != j) && (tmp(i,j) != 0))
476 if (length(tmp) != matlen)
480 if (gmat(i,i) != tmp(i))
484 tmp = reshape(gmat,prod(size(gmat)),1);
485 if (length(tmp) != prod(size(gmat)))
488 if (exp(log(gf([1:n],m))) != [1:n])
492 if (tmp .* tmp != gmat)
497 fprintf(" Unary operators: ");
506 if (any(tmp(2:length(tmp))))
512 if (gmat(i,j) != tmp(j,i))
518 fprintf(" Arithmetic operators: ");
519 if (any(gmat + gmat))
522 multbl = gcol * grow;
523 elsqr = gcol .* gcol;
524 elsqr2 = gcol .^ gf(2,m);
525 for i=1:length(elsqr)
526 if (elsqr(i) != multbl(i,i))
530 for i=1:length(elsqr)
531 if (elsqr(i) != elsqr2(i))
535 tmp = grow(2:length(grow)) ./ gcol(2:length(gcol))';
536 if (length(tmp) != n || any(tmp != ones(1,length(grow)-1)))
540 fprintf(" Logical operators: ");
541 if (grow(1) != gzero || grow(2) != gone || grow(2^m) != n)
544 if (!(grow(1) == gzero) || any(grow != gcol'))
549 fprintf(" Polynomial manipulation: ");
550 poly1 = gf([2,4,5,1],3);
552 sumpoly = poly1 + [0,0,poly2]; ## Already test "+"
553 mulpoly = conv(poly1, poly2); ## multiplication
554 poly3 = [poly,remd] = deconv(mulpoly, poly2);
555 if (!isequal(poly1,poly3))
561 x0 = gf([0,1,2,3],3);
562 y0 = polyval(poly1, x0);
564 y1 = alph * x0.^3 + alph.^2 * x0.^2 + (alph.^2+1) *x0 + 1;
568 roots1 = roots(poly1);
569 ck1 = polyval(poly1, roots1);
574 bpoly = bi2de(b.x,"left-msb");
575 if (bpoly != alph.prim_poly)
580 mpol = minpol(c2(1));
582 if (mpol != minpol(c2(i)))
588 fprintf(" Linear Algebra: ");
595 if (any(g1*gmat != eye(matlen)))
603 granmat = gf(floor(2^m*rand(matlen)),m);
604 matdet = det(granmat);
606 matrank = rank(granmat);
607 smallcol = gf([0:matlen-1],m)';
608 sol1 = granmat \ smallcol;
609 sol2 = smallcol' / granmat;
610 if (any(granmat * sol1 != smallcol))
613 if (any(sol2 * granmat != smallcol'))
617 fprintf(" Signal Processing functions: ");
618 b = gf([1,0,0,1,0,1,0,1],m);
620 x = gf([1,zeros(1,99)],m);
621 y0 = filter(b, a, x);
622 y1 = conv(grow+1, grow);
623 y2 = grow * convmtx(grow+1, length(grow));
627 [y3,remd] = deconv(y2, grow+1);
635 x = gf(floor(2^m*rand(n,1)),m);
637 ifm = dftmtx(1/alph);
655 unwind_protect_cleanup
656 page_screen_output(pso);
659 usage("comms: Unknown argument");
664 %! try comms("test");
665 %! catch disp(lasterr()); end