[ Main Page ]

Scilab / Octave¤ÎÈæ³Ó - ¥¢¥À¥Þ¡¼¥ëÊÑ´¹

Freeverb3¤Î³«È¯¤ÎºÝ¤Ë¡¢»Ä¶Á±é»»¤Î¤¿¤á¤Î¥Ç¥£¥ì¥¤¥é¥¤¥ó³È»¶¤Î¤¿¤á¤Î¹ÔÎó¤È¤·¤Æ»È¤ï¤ì¤Æ¤¤¤ë Hadamard matrix (¥¢¥À¥Þ¡¼¥ë¹ÔÎó) ¤ò³Ø½¬¤¹¤ë¤¿¤á¤ËScilab¤ÈOctave¤ò»È¤Ã¤¿ºÝ¤Îµ­Ï¿¡£¼¹É®»þ¤ÏScilab-6.0.0 / Octave-4.2.1¤Ç¹Ô¤Ã¤¿¤¬¡¢Scilab¤Ï5·Ï¤«¤é6·Ï¤Ë¤Ê¤Ã¤Æ¤«¤Ê¤êÊѤï¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢ °ìÉô¤Î¥Þ¥¯¥íÅù¤Ç¤Ï¸ß´¹À­¤¬¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤ë¡£5·Ï¤ÎÃæ¤Ç¤â¡¢Âбþ¤¹¤ëToolbox¤¬°Û¤Ê¤ê¡¢¸ß´¹À­¤Ï¤«¤Ê¤ê˳¤·¤¤¤È¤³¤í¤¬¤¢¤ë¡£¸å¤Î¹àÌܤǤϡ¢Á°¤Î¹àÌܤδؿô¤Ë°Í¸¤·¤Æ¤¤¤ëÉôʬ¤â¤¢¤ë¤Î¤Ç¡¢ºÇ½é¤«¤é½ç¤Ë¼Â¹Ô¤¹¤ë¡£
üŪ¤Ë¸À¤¨¤Ð¡¢Matlab¤ÈƱ¤¸¤è¤¦¤ËScilab¤ò»È¤ª¤¦¤È¤¹¤ë¤È¡¢¤«¤Ê¤ê¤Î´Ø¿ô¤ò³°ÉôToolbox¤Ç¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ëɬÍפ¬½Ð¤Æ¤¯¤ë¤¿¤á¡¢¥³¥¢¤Î¤ß¤Î¥¤¥ó¥¹¥È¡¼¥ë¤Î¤ß¤ÇMatlab¤ÎSignal Processing Toolbox¤ä Image Processing Toolbox¤ÈƱÅù¤Ë»È¤¤¤¿¤¤¿Í¤Ë¤È¤Ã¤Æ¤ÏOctave¤¬¤ª´«¤á¤Ç¤¢¤ë¡£Scilab¤ÎÍ¥°ÌÀ­¤Ï¡¢XcosÅù¤ÎGUI¥×¥í¥°¥é¥ß¥ó¥°¤¬¤Ç¤­¤ë½ê¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ë¡£

±Ñ¸ìÈÇWindows¤ÇÆüËܸì¥í¥±¡¼¥ë¤Î¾õÂ֤ǵ¯Æ°¤¹¤ë¤Èʸ»ú²½¤±¤¹¤ë¤³¤È¤¬¤¢¤ê¡¢¤½¤Î¾ì¹ç¤Ï¡¢²¼µ­¤Î¤è¤¦¤Ë±Ñ¸ì¤ò»ØÄꤹ¤ë¤ÈÎɤ¤¡£

Scilab

	  setdefaultlanguage('en_US')
	

Hadamard matrix¤ÎÀ¸À®

Octave¤Ç¤Ïɸ½à¤Çhadamard()´Ø¿ô¤¬»È¤¨¤ë¤¬¡¢Scilab¤Ç¤Ïɸ½à¤Ç¤Ï»È¤¨¤Ê¤¤¤è¤¦¤Ç¤¢¤ë¡£¹ÔÎóÀ¸À®¥Þ¥¯¥í¤¬³«È¯¤µ¤ì¤Æ¤¤¤ë¾¡¢ Scilab 5·Ï¤Ë¤ÏImage_Processing_Toolbox_2(IPT2)¤¬¤¢¤ê¡¢hadamard()¤äfwht()¤¬»È¤¨¤ë¡£¤³¤³¤Ë¤ÏÀè½Ò¤Î¥Þ¥¯¥í¤Èû¤¯¤·¤¿´Ø¿ô¤òºÜ¤»¤ë¡£ ⤷¡¢¤³¤ÎToolbox¤Îfwht()¤ÏMatlab¤Îfwht()¤ÈƱ¤¸¤¯¡¢Æó¼¡¸µ¤Î¹ÔÎó¤òÆþÎϤ·¤Æ¤âÎóËè¤Ë±é»»¤¹¤ë¤À¤±¤Ç¡¢Æó¼¡¸µ¤Î½èÍý¤ò¤·¤Æ¤¯¤ì¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢½èÍý¤Ï¤Ç¤­¤º¡¢¸å½Ò¤ÎÊýË¡¤ÇÂбþ¤¹¤ë¡£

Scilab

	  // makematrix_hadamard.sci
	  // Copyright (C) 2008-2009 - INRIA - Michael Baudin
	  //
	  // This file must be used under the terms of the CeCILL.
	  // This source file is licensed as described in the file COPYING, which
	  // you should have received as part of this distribution.  The terms
	  // are also available at
	  // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt

	  //
	  // makematrix_hadamard --
	  //   Returns the Hadamard matrix of size n.
	  //   n is expected to be a power of 2.
	  // Arguments, input
	  //  n : the size of the matrix to return
	  // Reference
	  //  http://en.wikipedia.org/wiki/Hadamard_matrix
	  //
	  function a = makematrix_hadamard ( n )
	    pow2n = log2(n);
	    if ( n - 2^pow2n <>0 ) then
	      errmsg = msprintf(gettext("%s: n is expected to be a power of 2."), "makematrix_hadamard");
	      error(errmsg)
	    end
	    if n==1 then
	      a = ones(1,1)
	    else
	      m = int(n/2)
	      b = makematrix_hadamard(m)
	      a = zeros(n,n)
	      a(1:m,1:m) = b(1:m,1:m)
	      a(1:m,m+1:n) = b(1:m,1:m)
	      a(m+1:n,1:m) = b(1:m,1:m)
	      a(m+1:n,m+1:n) = -b(1:m,1:m)
	    end
	  endfunction

	  // hadamard.sci
	  // Copyright (C) 2008-2009 - INRIA - Michael Baudin
	  //
	  // This file must be used under the terms of the CeCILL.
	  // This source file is licensed as described in the file COPYING, which
	  // you should have received as part of this distribution.  The terms
	  // are also available at
	  // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt

	  //
	  // hadamard --
	  //   Returns the Hadamard matrix of size n.
	  //   n is expected to be a power of 2.
	  // Arguments, input
	  //  n : the size of the matrix to return
	  // Reference
	  //  http://en.wikipedia.org/wiki/Hadamard_matrix
	  //
	  function a = hadamard ( n )
	    a = makematrix_hadamard ( n );
	  endfunction
	
	  --> hadamard(4)
	   ans  =
	  
	     1.   1.   1.   1.
	     1.  -1.   1.  -1.
	     1.   1.  -1.  -1.
	     1.  -1.  -1.   1.
	

¥¨¥é¡¼¥Á¥§¥Ã¥¯Åù¤Ï¤Ê¤·¤Ç¤â¤Ã¤È´Êñ¤ÊÄêµÁ¤â¤Ç¤­¤ë¡£

	  function hmatrix=hadamard(n)
	  h=[1,1;1,-1]
	  hmatrix=h;
	    for n = 1:1:(log2(n)+1)-2
	      // kron() - Kronecker product (.*.)
	      hmatrix = hmatrix.*.h;
	    end
	  endfunction
	

¥¯¥í¥Í¥Ã¥«¡¼ÀÑ kron()¤Ï¡¢Scilab¡¢Octave¤ÎξÊý¤Ç»È¤¨¤ë¤¬¡¢Scilab¤Ç¤Ï¡¢.*.¤È¤¤¤¦±é»»»Ò¤¬»È¤¨¤ë¡£

Octave

	  GNU Octave, version 4.2.1
	  Copyright (C) 2017 John W. Eaton and others.
	  This is free software; see the source code for copying conditions.
	  There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
	  FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

	  Octave was configured for "x86_64-w64-mingw32".

	  Additional information about Octave is available at http://www.octave.org.

	  Please contribute if you find this software useful.
	  For more information, visit http://www.octave.org/get-involved.html

	  Read http://www.octave.org/bugs.html to learn how to submit bug reports.
	  For information about changes from previous versions, type 'news'.

	  >> hadamard(8)
	  ans =

	     1   1   1   1   1   1   1   1
	     1  -1   1  -1   1  -1   1  -1
	     1   1  -1  -1   1   1  -1  -1
	     1  -1  -1   1   1  -1  -1   1
	     1   1   1   1  -1  -1  -1  -1
	     1  -1   1  -1  -1   1  -1   1
	     1   1  -1  -1  -1  -1   1   1
	     1  -1  -1   1  -1   1   1  -1

	  >>
	

¥¢¥À¥Þ¡¼¥ë¹ÔÎó¤ÎÀ­¼Á¤«¤é¡¢¥Ó¥Ã¥È±é»»¤È¾ê;±é»»¤ÇÀ¸À®¤¹¤ë¤³¤È¤â¤Ç¤­¤ë¡£

	  dec2bin(0:7)-'0'
	  (dec2bin(0:7)-'0')'
	  mod((dec2bin(0:7)-'0') * (dec2bin(0:7)-'0')', 2)
	  mod((dec2bin(0:7)-'0') * (dec2bin(0:7)-'0')', 2) * (-2) + 1
	
	  ans =

	     0   0   0
	     0   0   1
	     0   1   0
	     0   1   1
	     1   0   0
	     1   0   1
	     1   1   0
	     1   1   1

	  ans =

	     0   0   0   0   1   1   1   1
	     0   0   1   1   0   0   1   1
	     0   1   0   1   0   1   0   1
	  
	  ans =
	  
	     0   0   0   0   0   0   0   0
	     0   1   0   1   0   1   0   1
	     0   0   1   1   0   0   1   1
	     0   1   1   0   0   1   1   0
	     0   0   0   0   1   1   1   1
	     0   1   0   1   1   0   1   0
	     0   0   1   1   1   1   0   0
	     0   1   1   0   1   0   0   1
	  
	  ans =

	     1   1   1   1   1   1   1   1
	     1  -1   1  -1   1  -1   1  -1
	     1   1  -1  -1   1   1  -1  -1
	     1  -1  -1   1   1  -1  -1   1
	     1   1   1   1  -1  -1  -1  -1
	     1  -1   1  -1  -1   1  -1   1
	     1   1  -1  -1  -1  -1   1   1
	     1  -1  -1   1  -1   1   1  -1
	

Hadamard transform (¥¢¥À¥Þ¡¼¥ëÊÑ´¹) ¤Î½àÈ÷¤ÈGray code (¥°¥ì¥¤¥³¡¼¥É)

¾åµ­¤ÇÀ¸À®¤µ¤ì¤¿¹ÔÎó¤òHadamard ordered (Natural ordered¤Þ¤¿¤ÏSylvester) Matrix¤È¸Æ¤Ö¤¬¡¢¿®¹æ½èÍý¤ä²èÁü½èÍýÅù¤Ç¹Ô¤¦¤è¤¦¤ÊÄã¼þÇȤ«¤é¹â¼þÇȤ˽ç¤ËÊÑ´¹¤µ¤ì¤¿¹ÔÎó¤â¤¢¤ê¡¢ ¤³¤ì¤ÏSequency ordered Walsh-Hadamard Matrix¤È¸Æ¤Ö¡£¤³¤Î·¸¿ô½ç½ø¤Ï¡¢ ¥°¥ì¥¤¥³¡¼¥É¤Î¥Ó¥Ã¥Èȿž¤Î½ç¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¤½¤Î¾¤Ë·¸¿ô½ç½ø¤¬¥°¥ì¥¤¥³¡¼¥É½ç¤ÎDyadic ordered (Paley ordered) Matrix¤È¤¤¤¦¤Î¤â¤¢¤ë¡£ ºÇ¶á¤À¤ÈFPGA¼ÂÁõ¤ÎÏÀʸ¤Ë´Ê·é¤ÊÀâÌÀ¤¬ºÜ¤Ã¤Æ¤¤¤ë¡£ Ä̾ï¤Î¥Ð¥¿¥Õ¥é¥¤±é»»¤Ë¤è¤ëFast Walsh-Hadamard Transform (¹â®¥¢¥À¥Þ¡¼¥ëÊÑ´¹)¤ò¹Ô¤¦¤¿¤á¤Ë¤Ï¡¢ Hadamard ordered Matrix¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤º¡¢¤½¤Î¾¤Î¹ÔÎó¤Ë¤è¤ë½èÍý¤ÇFWHT¤ò¹Ô¤¦¤Ë¤Ï¡¢ÆþÎÏ½ç½ø¤ÎÆþ¤ìÂØ¤¨¤¬É¬ÍפȤʤ롣 ¤Á¤Ê¤ß¤Ë¡¢DCT¤äDFT¤È°ã¤Ã¤Æ·¸¿ô¤¬1¤«-1¤Ç¡¢¤µ¤é¤Ë·×»»¤Î·Á¤«¤é¡¢¥Ð¥¿¥Õ¥é¥¤±é»»¤Ï¤É¤Á¤é¤«¤é¹Ô¤Ã¤Æ¤âÌäÂê¤Ê¤¤¤·¡¢½ç½ø¤ò¥·¥ã¥Ã¥Õ¥ë¤·¤Æ¤âÌäÂê¤Ê¤¤¡£Wikipedia¤Î¿Þ¤Ë¤Ï±ó¤¤½ê¤È¤Î±é»»¤«¤é¤ÎÊýË¡¤¬ Î㼨¤µ¤ì¤Æ¤¤¤ë¤¬¡¢ÏÀʸ¤Ë¤è¤Ã¤Æ¤ÏÎÙÆ±»Î¤Î±é»»¤«¤é¤ÎÊýË¡¤â¼¨¤·¤Æ¤¢¤ê¡¢¼ÂÁõ¾å¤ÏÎÙÆ±»Î¤Î±é»»¤«¤é¤ÎÊý¤¬Ê¬¤«¤ê¤ä¤¹¤¤¤È»×¤¦¡£

Fig. 3 from Impulse-response and reverberation-decaymeasurements made by using pseudorandom sequence Chu, W. T.

Figure from Wikipedia - Fast Walsh Hadamard transform

Discrete Walsh-Hadamard Transform (Î¥»¶¥¦¥©¥ë¥·¥å¡¦¥¢¥À¥Þ¡¼¥ëÊÑ´¹) - MATLAB & Simulink Example - MathWorks¤òScilab¤ÈOctave¤Ç¼Â¹Ô¤·¤¿Îã¡£ Matlab¤ÈScilab¤Ï»÷¤Æ¤¤¤ë¤è¤¦¤ÇºÙ¤«¤¤´Ø¿ôÅù¤Ë¸ß´¹À­¤¬¤Ê¤¯¡¢°Õ³°¤Ë¶ìÏ«¤¹¤ë¤³¤È¤¬Â¿¤¤¡£Octave¤Ë¤Ïfwht()ifwht()¤¬¤¢¤ë¤¬Scilab¤Ë¤Ï¤Ê¤¤¡£¤³¤ÎMatlab¤ÎÎã¤Ç¤Ï¡¢ Octave¤Ç¤Ï¤Û¤ÜÌäÂê¤Ê¤¯Æ°¤¤¤¿¡£Scilab¤Ë¤ÏImage Processing Toolbox¤¬¤¢¤ê¡¢¤³¤ÎÃæ¤ËWalsh transform¤ÈHadamard transform¤¬Æþ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢ ¤³¤ì¤ò»È¤¦¾ì¹ç¤Ë¤ÏÊÌÅÓ¥¤¥ó¥¹¥È¡¼¥ë¤¬É¬ÍפǤ¢¤ë¡£

Walsh matrix¤Î½ç½ø¤Î¥Ó¥Ã¥È±é»»¤¬¤ï¤«¤ê¤Ë¤¯¤¤¤¬¡¢¥°¥ì¥¤¥³¡¼¥É¤Î¥Ó¥Ã¥ÈµÕž¤·¤¿ÃͤǹÔÎó¤ÎÎó¤òÀ°Î󤵤»¤Æ¤¤¤ë¡£ ¥°¥ì¥¤¥³¡¼¥É¤Ï¡¢±¦¥·¥Õ¥È¤·¤¿ÃͤȤÎXOR¤À¤¬¡¢²¼µ­¤ÎÎã¤Ç¤Ï¡¢Àè¤Ë¥Ó¥Ã¥ÈµÕž¤·¤Æ¤«¤éXOR¤·¤Æ¤¤¤ë¡£

Scilab

	  // Gray code
	  function list = graycode(N)
	    P=2^N;
	    list = dec2bin(bitxor(int((0:P-1)/2),0:P-1))';
	  endfunction
	  
	  graycode(3)
	  graycode(4)
	
	  --> graycode(3)
	   ans  =

	  !000  !
	  !     !
	  !001  !
	  !     !
	  !011  !
	  !     !
	  !010  !
	  !     !
	  !110  !
	  !     !
	  !111  !
	  !     !
	  !101  !
	  !     !
	  !100  !


	  --> graycode(4)
	   ans  =

	  !0000  !
	  !      !
	  !0001  !
	  !      !
	  !0011  !
	  !      !
	  !0010  !
	  !      !
	  !0110  !
	  !      !
	  !0111  !
	  !      !
	  !0101  !
	  !      !
	  !0100  !
	  !      !
	  !1100  !
	  !      !
	  !1101  !
	  !      !
	  !1111  !
	  !      !
	  !1110  !
	  !      !
	  !1010  !
	  !      !
	  !1011  !
	  !      !
	  !1001  !
	  !      !
	  !1000  !
	

Octave

	  % Gray code	  
	  function list = graycode(N)
	    P=2^N;
	    list = dec2bin(bitxor(bitshift(0:P-1,-1),0:P-1));
	  end
	  
	  graycode(3)
	  graycode(4)
	
	  >> graycode(3)
	  ans =

	  000
	  001
	  011
	  010
	  110
	  111
	  101
	  100

	  >> graycode(4)
	  ans =

	  0000
	  0001
	  0011
	  0010
	  0110
	  0111
	  0101
	  0100
	  1100
	  1101
	  1111
	  1110
	  1010
	  1011
	  1001
	  1000
	

Scilab

	  // Length of Walsh (Hadamard) functions
	  N = 8;
	  hadamardMatrix=hadamard(N)

	  // Hadamard index
	  HadIdx = 0:N-1;
	  // Number of bits to represent the index
	  M = log2(N)+1;

	  //binHadIdx = fliplr(dec2bin(HadIdx,M))-'0';
	  //´Ø¿ô flipdim(A,1) ¤Ï flipud(A) ¤ÈƱ¤¸
	  //´Ø¿ô flipdim(A,2) ¤Ï´Ø¿ô fliplr(A) ¤ÈƱ¤¸

	  // Bit reversing of the binary index
	  binHadIdx = strrev(dec2bin(HadIdx(:),M))
	  // Pre-allocate memory
	  binSeqVdx = zeros(N,M);
	  for k = 1:1:N
	      binSeqVdx(k,:) = strtod(strsplit(binHadIdx(k)))';
	  end

	  // Pre-allocate memory
	  binSeqIdx = zeros(N,M-1);
	  //for k = M:-1:2
	  //  binSeqIdx(:,k) = xor(binHadIdx(:,k),binHadIdx(:,k-1));
	  //end
	  for k = M:-1:2
	    binSeqIdx(:,k) = bitxor(binSeqVdx(:,k),binSeqVdx(:,k-1));
	  end

	  // Binary to integer sequency index
	  //SeqIdx = binSeqIdx*(2^((M-1:-1:0)'));
	  for k = 1:1:N
	    // Binary sequency index 
	    HadIdx(k) = bin2dec(strcat(string(binSeqIdx(k,:))));
	  end

	  // 1-based indexing
	  walshMatrix = hadamardMatrix(HadIdx+1,:)
	
	   hadamardMatrix  = 
	  
	     1.   1.   1.   1.   1.   1.   1.   1.
	     1.  -1.   1.  -1.   1.  -1.   1.  -1.
	     1.   1.  -1.  -1.   1.   1.  -1.  -1.
	     1.  -1.  -1.   1.   1.  -1.  -1.   1.
	     1.   1.   1.   1.  -1.  -1.  -1.  -1.
	     1.  -1.   1.  -1.  -1.   1.  -1.   1.
	     1.   1.  -1.  -1.  -1.  -1.   1.   1.
	     1.  -1.  -1.   1.  -1.   1.   1.  -1.
	  
	   walshMatrix  = 
	  
	     1.   1.   1.   1.   1.   1.   1.   1.
	     1.   1.   1.   1.  -1.  -1.  -1.  -1.
	     1.   1.  -1.  -1.  -1.  -1.   1.   1.
	     1.   1.  -1.  -1.   1.   1.  -1.  -1.
	     1.  -1.  -1.   1.   1.  -1.  -1.   1.
	     1.  -1.  -1.   1.  -1.   1.   1.  -1.
	     1.  -1.   1.  -1.  -1.   1.  -1.   1.
	     1.  -1.   1.  -1.   1.  -1.   1.  -1.
	

Octave

	  pkg load signal

	  N = 8;  % Length of Walsh (Hadamard) functions
	  hadamardMatrix = hadamard(N)

	  % Hadamard index
	  HadIdx = 0:N-1;
	  % Number of bits to represent the index
	  M = log2(N)+1;

	  % Bit reversing of the binary index
	  binHadIdx = fliplr(dec2bin(HadIdx,M))-'0';
	  % Pre-allocate memory
	  binSeqIdx = zeros(N,M-1);
	  for k = M:-1:2
	    % Binary sequency index 
	    binSeqIdx(:,k) = xor(binHadIdx(:,k),binHadIdx(:,k-1));
	  end
	  % Binary to integer sequency index
	  SeqIdx = binSeqIdx*pow2((M-1:-1:0)');
	  % 1-based indexing
	  walshMatrix = hadamardMatrix(SeqIdx+1,:)
	
	  hadamardMatrix =

	     1   1   1   1   1   1   1   1
	     1  -1   1  -1   1  -1   1  -1
	     1   1  -1  -1   1   1  -1  -1
	     1  -1  -1   1   1  -1  -1   1
	     1   1   1   1  -1  -1  -1  -1
	     1  -1   1  -1  -1   1  -1   1
	     1   1  -1  -1  -1  -1   1   1
	     1  -1  -1   1  -1   1   1  -1

	  walshMatrix =

	     1   1   1   1   1   1   1   1
	     1   1   1   1  -1  -1  -1  -1
	     1   1  -1  -1  -1  -1   1   1
	     1   1  -1  -1   1   1  -1  -1
	     1  -1  -1   1   1  -1  -1   1
	     1  -1  -1   1  -1   1   1  -1
	     1  -1   1  -1  -1   1  -1   1
	     1  -1   1  -1   1  -1   1  -1
	
	  N = 8;
	  H = hadamard(N);
	  x = 8.*H(1,:) + 12.*H(3,:) + 18.*H(5,:) + 10.*H(8,:);
	  // fwht(x,8,'hadamard')
	  y = x * hadamardMatrix / N
	  // ifwht(y,8,'hadamard')
	  z = y * hadamardMatrix
	  norm(x-z)
	
	   y  = 
	  
	     8.   0.   12.   0.   18.   0.   0.   10.
	  
	   z  = 
	  
	     48.   28.   4.   24.  -8.   12.  -12.  -32.

	   ans  = 
	  
	     0.
	
	  % Fast Walsh-Hadamard transform
	  y1 = fwht(walshMatrix)
	  
	  N = 8;
	  H = hadamard(N);
	  x = 8.*H(1,:) + 12.*H(3,:) + 18.*H(5,:) + 10.*H(8,:);
	  y = fwht(x,N,'hadamard')
	  xHat = ifwht(y,N,'hadamard')
	  norm(x-xHat)
	
	  y1 =

	     1   0   0   0   0   0   0   0
	     0   1   0   0   0   0   0   0
	     0   0   1   0   0   0   0   0
	     0   0   0   1   0   0   0   0
	     0   0   0   0   1   0   0   0
	     0   0   0   0   0   1   0   0
	     0   0   0   0   0   0   1   0
	     0   0   0   0   0   0   0   1

	  y =

	      8    0   12    0   18    0    0   10

	  xHat =
	  
	     48   28    4   24   -8   12  -12  -32
	  
	  ans = 0
	

Sequency ordered / Dyadic ordered Walsh-Hadamard Matrix

Octave¤ÎÊý¤¬¥Ó¥Ã¥È±é»»Åù¤Î´Ø¿ô¤¬»È¤¤¤ä¤¹¤¯¡¢¾åµ­¤Î¹ÔÎó½ç¤ÎÆþ¤ìÂØ¤¨¤Ï¤â¤¦¾¯¤·´Êñ¤Ëɽµ­¤Ç¤­¤ë¡£ Octave¤Ç¤Ï¡¢»ØÄꤷ¤Ê¤±¤ì¤Ð¡¢fwht()¤Ïsequency¤¬µ¬Äê¤Ç¤¢¤ê¡¢¤³¤ì¤ÏMatlab¤ÈƱ¤¸Æ°ºî¤Ç¤¢¤ë¡£

Scilab

	  HadIdx
	
	   HadIdx  = 
	  
	     0.   4.   6.   2.   3.   7.   5.   1.
	
	  x = [19 -1 11 -9 -7 13 -15 5];
	  // y = fwht(x)
	  y = x * walshMatrix / 8
	
	   y  = 
	  
	     2.   3.   0.   4.   0.   0.   10.   0.
	

Octave

	  % Sequency (Walsh) Ordered Walsh-Hadamard Matrix
	  pkg load signal
	  N=8;
	  bitand(bitxor(bitshift(bitrevorder(0:N-1),1),bitrevorder(0:N-1)),(N-1))
	  bitand(bitrevorder(bitxor(bitshift(0:N-1,1),0:N-1)),(N-1))

	  % Dyadic (Paley) ordered Matrix
	  bitrevorder(0:N-1)

	  paleyMatrix = hadamardMatrix(bitrevorder(0:N-1)+1,:)
	  fwht(paleyMatrix,N,'dyadic')
	
	  >> bitand(bitxor(bitshift(bitrevorder(0:N-1),1),bitrevorder(0:N-1)),(N-1))
	  ans =

	     0   4   6   2   3   7   5   1

	  >> bitand(bitrevorder(bitxor(bitshift(0:N-1,1),0:N-1)),(N-1))
	  ans =

	     0   4   6   2   3   7   5   1

	  >>
	  >> % Dyadic (Paley) ordered Matrix
	  >> bitrevorder(0:N-1)
	  ans =

	     0   4   2   6   1   5   3   7

	  >>
	  >> paleyMatrix = hadamardMatrix(bitrevorder(0:N-1)+1,:)
	  paleyMatrix =

	     1   1   1   1   1   1   1   1
	     1   1   1   1  -1  -1  -1  -1
	     1   1  -1  -1   1   1  -1  -1
	     1   1  -1  -1  -1  -1   1   1
	     1  -1   1  -1   1  -1   1  -1
	     1  -1   1  -1  -1   1  -1   1
	     1  -1  -1   1   1  -1  -1   1
	     1  -1  -1   1  -1   1   1  -1

	  >> fwht(paleyMatrix,N,'dyadic')
	  ans =

	     1   0   0   0   0   0   0   0
	     0   1   0   0   0   0   0   0
	     0   0   1   0   0   0   0   0
	     0   0   0   1   0   0   0   0
	     0   0   0   0   1   0   0   0
	     0   0   0   0   0   1   0   0
	     0   0   0   0   0   0   1   0
	     0   0   0   0   0   0   0   1
	
	  x = [19 -1 11 -9 -7 13 -15 5];
	  y = fwht(x)
	  z = fwht(x,8,'dyadic')
	  p = x*paleyMatrix/8
	  porder = bitrevorder(0:N-1);
	  fwht(x(porder+1),N,'hadamard')
	  fwht(x,N,'hadamard')(porder+1)
	
	  >> y = fwht(x)
	  y =
	  
	      2    3    0    4    0    0   10    0
	  
	  >> z = fwht(x,8,'dyadic')
	  z =
	  
	      2    3    4    0    0   10    0    0
	  
	  >> p = x*paleyMatrix/8
	  p =
	  
	      2    3    4    0    0   10    0    0
	  
	  >> porder = bitrevorder(0:N-1);
	  >> fwht(x(porder+1),N,'hadamard')
	  ans =
	  
	      2    3    4    0    0   10    0    0
	  >> fwht(x,N,'hadamard')(porder+1)
	  ans =
	  
	      2    3    4    0    0   10    0    0
	

Sequency ordered fast Hadamard transform

¥¢¥À¥Þ¡¼¥ëÊÑ´¹¤¬À¹¤ó¤Ë¸¦µæ¤µ¤ì¤Æ¤¤¤¿1970ǯÂå¤ÎËܤò¸¡º÷¤¹¤ë¤È¡¢sequency orderedÍѤιâ®ÊÑ´¹Ë¡¤âÄ󰯤µ¤ì¤Æ¤¤¤¿¡£ºÇ¶á¤Î¼ÂÁõ¤ò¸¡º÷¤·¤¿¤È¤³¤í¡¢MATLABÅù¤Î¿®¹æ½èÍý¤ÎʬÌî¤Ç¤Ï¾åµ­¤Î¥Ð¥¿¥Õ¥é¥¤±é»»¤ÈÆþ½ÐÎϤÎÃÖ´¹¤ò¼Â¹Ô¤¹¤ëÊýË¡¤¬Â¿¤«¤Ã¤¿¤¬¡¢ JuliaÍѤÎHadamard.jl¥Ñ¥Ã¥±¡¼¥¸¤Ç¤ÏSequecy orderedÍѤι⮥¢¥ë¥´¥ê¥º¥à¤¬¼ÂÁõ¤µ¤ì¤Æ¤¤¤¿¡£ Walsh Functions And Their Applications K Beauchamp by K. G. Beauchamp¤È¤¤¤¦1975ǯ½ÐÈǤÎËÜ (mirror)¤Ë¤Ï¿Þ¤ò´Þ¤á¤Æ¤«¤Ê¤ê¾Ü¤·¤¯½Ò¤Ù¤é¤ì¤Æ¤ª¤ê¡¢Fortran¤Ë¤è¤ë¼ÂÁõ¤âºÜ¤Ã¤Æ¤¤¤ë¤Î¤Ç°ìÉôžºÜ¤¹¤ë¡£ ⤷¡¢OCR¤Ë¤è¤ëÆÉ¤ß¼è¤ê¤Î¤¿¤á°ìÉô¸í¿¢¤Î²ÄǽÀ­¤¬¤¢¤ë¤Î¤È¡¢ºÇ¶á¤Î¥³¥ó¥Ñ¥¤¥é¤ËÄ̤·¤¿¾ì¹ç¥¨¥é¡¼¤¬½Ð¤ë²ÄǽÀ­¤¬¤¢¤ë¡£

Fig. 3.3

Fig. 3.5

Fig. 3.6

	  Appendix I 

	  A Signal processing computer programs 192
	  B Program summary 192 
	  C Fast Walsh transform routines FWT and FFWT 193 
	  D Fast Walsh transform routines FHT and FRT 195 

	  C2 Calling sequence 

	  CALL FWT (N,X, WORK) or CALL FFWT (N,X) 

	  where N is an integer constant or variable and must be a power of 2. X is the 
	  name of a real array which on input contains the N data samples and on 
	  output contains the transformed signal. WORK is an array dimensioned 
	  N/2 and is used for temporary work space. 

	  SUBROUTINE FWT(N,X,Y) 

	  C THIS ROUTINES PERFORMS A FAST WALSH TRANSFORM ON AN INPUT SERIES X 
	  C LEAVING THE TRANSFORMED RESULTS IN X, THE ARRAY Y IS USED FOR WORKING 
	  C SPACE. X AND Y ARE DIMENSIONED N WHICH MUST BE A POWER OF 2 
	  C THE RESULTS OF THIS WALSH TRANSFORM ARE IN SEQUENCY ORDER 

	  DIMENSION X(N) ,Y(N) 
	  N2=N/2 
	  M=ALOG2 (FLOAT (N) ) 
	  DO 4 L=1,M 
	   NY=0 
	   NZ=2** (L-1)
	   NZI=2*NZ 
	   NZN=N/NZI 
	   DO 3 I=1, NZN 
	    NX=NY+1 
	    NY=NY+NZ 
	    JS=(I-1) *NZI 
	    JD=JS+NZI+1 
	    DO 1 J=NX,NY 
	     JS=JS+1 
	     J2=J+N2 
	     Y(JS)=X(J)+X(J2) 
	     JD= JD-1 
	     Y ( JD) =ABS (X ( J) -X ( J2 ) ) 
	    1 CONTINUE 
	   3 CONTINUE 
	   CALL FMOVE (Y(1) ,X(1) ,N) 
	  4 CONTINUE 
	  RETURN 
	  END 


	  SUBROUTINE FFWT(N,X) 
	  C THIS SUBROUTINES PERFORMS AN IN PLACE FAST WALSH TRANSFORM LEAVING THE 
	  C TRANSFORMED VALUES IN SEQUENCY ORDER AFTER BIT-REVERSAL 

	  DIMENSION X (N) ,INT (24) 
	  M=ALOG2 (FLOAT (N) ) 
	  DO 10 1=1, M 
	   10 INT (I) =2** (M-l) 
	   DO 4 L=1,M 
	   NZ=2** (L-1) 
	   NZI=2*NZ 
	   NZN=N/NZI 
	   NZ2=NZ/2 
	   IF (NZ2.EQ.0) NZ2=NZ2+1 
	   DO 3 1=1, NZN 
	    JS=(I-1) *NZI 
	    Z=1.0 
	    DO 2 11=1,2 
	     DO 1 J=1,NZ2 
	     JS=JS+1 
	     J2=JS+NZ 
	     HOLD=X(JS) +Z*X(J2) 
	     Z=-Z 
	     X ( J2) =X(JS) +Z*X(J2) 
	     X ( JS) =HOLD 
	     Z=-Z 
	     1 CONTINUE 
	     IF (L.EQ. 1) GO TO 3 
	     Z=-1.0 
	    2 CONTINUE 
	   3 CONTINUE 
	  4 CONTINUE 

	  C BIT-REVERSAL SECTION 
	  C THE TRANSFORMED ARRAY IS REARRANGED INTO SEQUENCY ORDER 

	  NW=0 
	  DO 50 K = 1 , N 
	    C CHOOSE CORRECT INDEX & SWITCH ELEMENTS IF NOT ALREADY SWITCHED 
	    NW1=NW+1 
	    IF (NW1-K) 55,55,60 
	    60 HOLD=X (NW1 ) 
	    X(NW1)=X(K) 
	    X (K) =HOLD 
	    55 CONTINUE 
	  C BUMP UP SERIES BY ONE 
	    DO 70 1=1, M 
	    II=I 
	    IF (NW.LT.INT (I) ) GO TO 80 
	    MW=NW/INT(I) 
	    MWl=MW/2 
	    IF (MW.GT.2*MW1) GO TO 70 
	    GO TO 80 
	    70 NW=NW- INT ( I ) 
	    80 NW=NW+INT (II) 
	    50 CONTINUE 
	  RETURN 
	  END 
	
	  D Fast Walsh transform routines FHT and FRT 

	  The program FHT forms an alternative method to that of FWT described 
	  previously and is slightly faster. A signal flow diagram was given in Fig. 3.7 
	  which indicated the arithmetic steps required for the transformation of a 
	  time series for N = 16 samples. Solid lines meeting at an intersection indicate 
	  addition, whereas dotted lines indicate subtraction. 

	  A disadvantage of the Walsh transform for some purposes is that it is not 
	  invariant to circular time shifts of the series being transformed. The particu- 
	  lar sequence of calculations, used in FHT, enables a slight modification to be 
	  carried out in order to obtain a transform, known as the R-transform (see 
	  Section III I) which is invariant to circular time shift. This modification 
	  involves the replacement of the subtractive terms obtained during the 
	  interim calculations by their absolute values. However, unlike the Walsh transform,
	  the R-transform does not permit the original series to be recovered by
	  a second transformation, i.e. it is not its own inverse.


	  D.1 Program details 

	  The programs are written in FORTRAN for the ICL 1900 computer, using
	  all single precision variables. Program length for the routines are 26 
	  statements or 134 words. 

	  The data input and output is made via a calling sequence. A working space of N values is required. 


	  D2 Calling sequence 

	  CALL FHT (N,X,WORK) or CALL FRT (N,X,WORK) 

	  where N is an integer constant or variable and X and WORK are the names of real
	  arrays holding N samples. WORK is used for temporary working 
	  space. X contains the input signal on entry to the routine and the transformed series
	  is left in X in sequency order on return from the routine. 


	  SUBROUTINE FHT(N,X,Y) 

	  C THIS ROUTINES PERFORMS A FAST WALSH TRANSFORM ON AN INPUT SERIES X
	  C LEAVING THE TRANSFORMED RESULTS IN X, THE ARRAY Y IS USED FOR WORKING
	  C SPACE. X AND Y ARE DIMENSIONED N WHICH MUST BE A POWER OF 2
	  C THE RESULTS OF THIS HADAMARD TRANSFORM ARE IN SEQUENCY ORDER

	  DIMENSION X(N),Y(N)

	  N2=N/2 
	  N=ALOG2(FLOAT (N) ) 

	  DO 4 L=1,M
	   NY=0
	   NZ=2 ** (L-1)
	   NZI=2*NZ
	   NZN=N/NZI

	   DO 3 I=1, NZN
	    NX=NY+1
	    NY=NY+NZ
	    JS=(I-1)*NZI 
	    JD=JS+NZI+1 

	    DO 1 J=NX,NY 
	     JS=JS+1 
	     J2=J+N2 
	     Y(JS)=X(J)+X(J2)
	     JD=JD-1 
	     Y(JD)=X(J)-X(J2)
	    1 CONTINUE 
	   3 CONTINUE 
	   CALL FMOVE(Y(1),X(1),N) 
	  4 CONTINUE 
	  RETURN 
	  END 


	  D FAST WALSH TRANSFORM ROUTINES FHT AND FRT 


	  SUBROUTINE FRT(N,X,Y) 

	  C THIS ROUTINE PERFORMS A FASTER TRANSFORM ON AN INPUT SERIES X 
	  C LEAVING THE TRANSFORMED RESULTS IN X, THE ARRAY Y IS USED FOR WORKING 
	  C SPACE. X IS DIMENSIONED N AND Y N/2 , WHERE N MUST BE A POWER OF 2 
	  C THE RESULTS OF THIS R TRANSFORM ARE IN SEQUENCY ORDER 

	  N2=N/2 

	  DIMENSION X (N) ,Y(N2) 

	  M=ALOG2 (FLOAT (N) ) 
	  Z=-1.0 
	  DO 4 J=l, M 
	   NL=2** (M-J+l) 
	   Jl=2** (J-l) 
	   
	   DO 3 L=1 f Jl 
	    IS= (I-1) *N1+1 
	    II=0 
	    W=2 

	    DO 1 I=IS,IS+N1-1,2 
	     A=X(I) 
	     X (IS+Il) =A+X (I+1) 
	     II = II+1 
	     Y (II) =(X(I+1) -A) *W 
	     W=W*Z 
	    1 CONTINUE 
	    CALL FMOVE (Y ( 1 ) ,X(IS+Nl/2) ,Nl/2) 
	   3 CONTINUE 
	  4 CONTINUE 
	  RETURN 
	  END 
	

Scilab¤ÈOctave¤ÇNatural order¤ÈSequency order¤Î¥Ð¥¿¥Õ¥é¥¤±é»»¤ò¼ÂÁõ¤·¤Æ¤ß¤ë¡£Sequency order¤Î¥Ð¥¿¥Õ¥é¥¤±é»»¤Ç¤Ï¡¢Natural order¤Ç¤ÎÀè½Ò¤Î¤è¤¦¤Ê½ç½ø¥·¥ã¥Ã¥Õ¥ë¤¬Íø¤«¤Ê¤¤¤Î¤ÇÃí°Õ¡£

Scilab / Octave

fhtnat() 1D natural (Hadamard) ordered fast Hadamard transform
fhtseq() 1D sequency (Walsh) ordered fast Hadamard transform
²¼µ­¤ÏScilab¡¢Octave¤ÎξÊý¤Ç»ÈÍѲÄǽ¡£¾å½Ò¤ÎÄ̤ꡢfhtnat()¤Î
for level=1:log2(N)
¤Ï
for level=log2(N):-1:1
¤Î¤è¤¦¤ËµÕ½ç¤Ç¤â²Ä¡£

	  function data=fhtnat(data)
	  N = length(data);
	  tmp = zeros(1,N);
	  level = 1;
	  for level=1:log2(N)
	    addbin = repmat([ones(1,2^(level-1)), zeros(1,2^(level-1))],1,2^(log2(N)-level));
	    addindex = find(addbin==1);
	    subindex = find(addbin==0);
	    tmp(addindex) = data(addindex) + data(subindex);
	    tmp(subindex) = data(addindex) - data(subindex);
	    data = tmp;
	  end
	  data = data/N;
	  endfunction
	  
	  function data=fhtseq(data)
	  N = length(data);
	  tmp = zeros(1,N);
	  addindex2 = find(repmat([1,0],1,N/2)==1);
	  subindex2 = find(repmat([1,0],1,N/2)==0);
	  for level=log2(N):-1:2
	    addbin = repmat([ones(1,2^(level-1)), zeros(1,2^(level-1))],1,2^(log2(N)-level));
	    addindex = find(addbin==1);
	    subindex = find(addbin==0);
	  
	    decbin = repmat([1,0,0,1],1,N/4);
	    addindexf = find(decbin==1);
	    subindexf = find(decbin==0);
	    
	    tmp(addindex) = data(addindex2) + data(subindex2);
	    tmp(subindex) = data(addindexf) - data(subindexf);
	    data = tmp;
	  end
	  tmp(addindex2) = data(addindex2) + data(subindex2);
	  tmp(subindex2) = data(addindex2) - data(subindex2);
	  data = tmp;
	  
	  data = data/N;
	  endfunction
	

Octave

	  pkg load signal;
	  x = [19 -1 11 -9 -7 13 -15 5];
	  y = fwht(x,length(x),'hadamard')
	  y = fhtnat(x)
	  y = fwht(x,length(x),'sequency')
	  y = fhtseq(x)
	
	  y =
	  
	      2    0    4    0    3   10    0    0
	  
	  y =
	  
	      2    0    4    0    3   10    0    0

	  y =
	  
	      2    3    0    4    0    0   10    0
	  
	  y =
	  
	      2    3    0    4    0    0   10    0
	

¾¤Îsequency ordered fast Hadamard transform¤Î¼ÂÁõ¤ò¸«¤ë¤È¡¢¾¯¤·½ç½ø¤òÊѤ¨¤¿ÊýË¡¤¬Îɤ¯»È¤ï¤ì¤Æ¤¤¤ë¤è¤¦¤À¡£TVAL3 (TV minimization by Augmented Lagrangian and ALternating direction ALgorithms)¤Ç¼ÂÁõ¤µ¤ì¤Æ¤¤¤ëÊýË¡¤Èµ­½Ò¤µ¤ì¤Æ¤¤¤ë¤â¤Î¤¬Â¿¤¤¤¬¡¢¾å¤ÎFortran¤Î¥³¡¼¥É¤ÈƱ¤¸ÊýË¡¤Ç¤¢¤ë¡£ ¤â¤Á¤í¤ó¡¢¤³¤ÎÊýË¡¤â½ç½ø¤òµÕ¤Ë¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡£

Octave

	  function data=fhtseqv2(data)
	  N = length(data);
	  tmp = zeros(1,N);

	  addindex2 = find(repmat([1,0],1,N/2)==1);
	  subindex2 = find(repmat([1,0],1,N/2)==0);
	  tmp(addindex2) = data(addindex2) + data(subindex2);
	  tmp(subindex2) = data(addindex2) - data(subindex2);
	  data = tmp;

	  addindexf = find(repmat([1,0,0,1],1,N/4)==1);
	  subindexf = find(repmat([1,0,0,1],1,N/4)==0);

	  for level=2:1:log2(N)
	    vecbin = repmat([ones(1,2^(level-1)), zeros(1,2^(level-1))],1,2^(log2(N)-level));
	    addindex = find(vecbin==1);
	    subindex = find(vecbin==0);
	    tmp(addindexf) = data(addindex) + data(subindex);
	    tmp(subindexf) = data(addindex) - data(subindex);
	    data = tmp;
	  end
	  data = data/N;
	  endfunction

	  pkg load signal;
	  x = [19 -1 11 -9 -7 13 -15 5];
	  y = fwht(x,length(x),'sequency')
	  y = fhtseqv2(x)
	
	  y =
	  
	      2    3    0    4    0    0   10    0
	  
	  y =
	  
	      2    3    0    4    0    0   10    0
	

Python

Fast Walsh-Hadamard Transform in Python¤«¤é¤ÎÈ´¿è¡£

	  def FWHT(x):
	      """ Fast Walsh-Hadamard Transform
	      Based on mex function written by Chengbo Li@Rice Uni for his TVAL3 algorithm.
	      His code is according to the K.G. Beauchamp's book -- Applications of Walsh and Related Functions.
	      """
	      x = x.squeeze()
	      N = x.size
	      G = N/2 # Number of Groups
	      M = 2 # Number of Members in Each Group

	      # First stage
	      y = np.zeros((N/2,2))
	      y[:,0] = x[0::2] + x[1::2]
	      y[:,1] = x[0::2] - x[1::2]
	      x = y.copy()
	      # Second and further stage
	      for nStage in xrange(2,int(log(N,2))+1):
	          y = np.zeros((G/2,M*2))
	          y[0:G/2,0:M*2:4] = x[0:G:2,0:M:2] + x[1:G:2,0:M:2]
	          y[0:G/2,1:M*2:4] = x[0:G:2,0:M:2] - x[1:G:2,0:M:2]
	          y[0:G/2,2:M*2:4] = x[0:G:2,1:M:2] - x[1:G:2,1:M:2]
	          y[0:G/2,3:M*2:4] = x[0:G:2,1:M:2] + x[1:G:2,1:M:2]
	          x = y.copy()
	          G = G/2
	          M = M*2
	      x = y[0,:]
	      x = x.reshape((x.size,1))
	      return x/float(N)
	

C++ (Matlab MEX)

TVAL3¤«¤é¤ÎÈ´¿è¡£

	  /*=================================================================
	   *
	   * \file fWHtrans.cpp
	   *
	   *
	   * This code computes the (real) fast discrete Walsh-Hadamard transform with sequency order according to the K.G. Beauchamp's book -- Applications of Walsh and Related Functions.
	   *
	   *
	   * This file is written by Chengbo Li from Computational and Applied Mathematics Department of Rice University.
	   *
	   *
	   * This is a MEX-file for MATLAB.
	   *
	   * 02/15/2010
	   *
	   *=================================================================*/
	  #include <math.h>
	  #include "mex.h"
	  #include "matrix.h"
	  //#include <stdio.h>
	  //#include <stdlib.h>
	  // #include <malloc.h>
	  // #include <stack>


	  //! Matlab entry function
	  /*!
	   * \param nlhs number of left-hand-side output arguments
	   * \param plhs mxArray of output arguments
	   * \param nrhs number of right-hand-side input arguments
	   * \param prhs mxArray of input arguments
	   */
	  void mexFunction( int nlhs, mxArray *plhs[],
	          int nrhs, const mxArray*prhs[] )
	          
	  {
	      int p, nStage, L, clm;
	      int i, j, m, n, N, J, K, M;
	      double *v_in, *v_out, *v_ext, *v_final, *temp;
	      
	      /* Check for proper number of arguments */
	      if (nrhs != 1) {
	          mexErrMsgTxt("Only one input arguments required.");
	      }
	      else if (nlhs > 1) {
	          mexErrMsgTxt("Too many output arguments.");
	      }
	      
	      /* Get the size and pointers to input data. */
	      m  = mxGetM(prhs[0]);
	      n  = mxGetN(prhs[0]);
	      
	      
	      /* Make sure that both input and output vectors have the length with 2^p where p is some integer. */
	      p = ceil(log2(m));
	      N = pow(2, p);
	      
	      plhs[0] = mxCreateDoubleMatrix(N, n, mxREAL);
	      
	      v_final = mxGetPr(plhs[0]);
	      v_in = mxGetPr(prhs[0]);
	      
	      /* Extend the input vector if necessary. */
	      v_ext = (double*) mxCalloc(N, sizeof(double));
	      v_out = (double*) mxCalloc(N, sizeof(double));
	      
	      for (clm=0; clm<n; clm++) {
	          
	          /* C is row major while Matlab is column major */
	          for (j=0; j<m; j++){
	              v_ext[j] = (v_in+clm*m)[j];
	          }
	          for (j=m; j<N; j++){
	              v_ext[j] = 0;
	          }
	          
	          
	          for (i=0; i<N-1; i = i+2) {
	              v_ext[i] = v_ext[i] + v_ext[i+1];
	              v_ext[i+1] = v_ext[i] - v_ext[i+1] * 2;
	          }
	          L = 1;
	          
	          /* main loop */
	          for (nStage = 2; nStage<=p; ++nStage){
	              M = pow(2, L);
	              J = 0;
	              K = 0; // difference between Matlab and C++
	              while (K<N-1){
	                  for (j = J;j < J+M-1; j = j+2){
	                      /* sequency order  */
	                      v_out[K] = v_ext[j] + v_ext[j+M];
	                      v_out[K+1] = v_ext[j] - v_ext[j+M];
	                      v_out[K+2] = v_ext[j+1] - v_ext[j+1+M];
	                      v_out[K+3] = v_ext[j+1] + v_ext[j+1+M];
	                      
	                      K = K+4;
	                  }
	                  
	                  J = J+2*M;
	              }
	              
	              temp = v_ext;
	              v_ext = v_out;
	              v_out = temp;
	              
	              L = L+1;
	          }
	          
	          /* Perform scaling of coefficients. */
	          for ( i =0; i<N; ++i){
	              (v_final+clm*N)[i] = v_ext[i]/N;
	          }
	      }
	      
	      /* Set free the memory. */
	      mxFree(v_out);
	      mxFree(v_ext);
	      
	      return;
	  }
	

Python 3 Tips

Python¤Ç¤â¹ÔÎó±é»»¤Ï²Äǽ¤Ç¡¢Scilab¤äOctave¤äMatlab°Ê³°¤Ë²¿¤«»È¤¦¸À¸ì¤È¤Ê¤ë¤È¤Þ¤ºµó¤²¤é¤ì¤ë¡£Python 2¤«¤éPython 3¤Ë¤Ê¤ê¤«¤Ê¤êÊѹ¹ÅÀ¤¬¤¢¤ë¤¬¡¢ ¥¢¥À¥Þ¡¼¥ëÊÑ´¹¤ò¼ÂÁõ¤·¤¿Îã¤òžºÜ¤¹¤ë¡£¾åµ­¤ÏPython 2ÍѤÀ¤Ã¤¿¤Î¤òPython 3ÍѤ˽ñ¤­Ä¾¤·¤¿¡£//¤Ë¤è¤ëÀ°¿ô½ü»»¤ä¡¢xrange¤ÎÊÑ´¹¡¢print¤Î¥Ö¥é¥±¥Ã¥È¤¬¼ç¤ÊÊѹ¹ÅÀ¤Ç¤¢¤ë¡£

FWHT.py

	  # -*- coding: utf-8 -*-
	  """
	  Created on Thu Jun 11 15:21:43 2015
	  Fast Walsh-Hadamard Transform with Sequency Order
	  Author: Ding Luo@Fraunhofer IOSB
	  """
	  from math import log
	  import numpy as np
	  import GrayCode
	  from time import clock

	  def get_sequency_list(inputArray):
	      """ Sort input 1D array into sequency order
	      Utilizes gray code generation from a Python recipe from Internet.
	      """
	      length = inputArray.size
	      bitlength = int(log(length,2))
	      # Gray Code
	      graycodes=GrayCode.GrayCode(bitlength)
	      # Bitreverse of gray code
	      bitreverse = [int(graycodes[i][::-1],2) for i in range(length)]
	      
	      outputArray = inputArray.copy()
	      outputArray[bitreverse] = inputArray[:]

	      return outputArray

	  def SFWHT(X):
	      """ 'Slower' Fast Walsh-Hadamard Transform
	      Step#1 Get sequency-ordered input
	      Step#2 Perform Hadamard Transform
	      """
	      x=get_sequency_list(X)
	      N = x.size
	      M = int(log(N,2))
	      out = x.copy()
	      for m in range(M):
	          outtemp = out.copy()         
	          step = 2**m
	          numCalc = 2**m
	          for g in range(0,N,2*step): # number of groups
	              for c in range(numCalc):
	                  index = g + c
	                  out[index] = outtemp[index] + outtemp[index+step]
	                  out[index+step] = outtemp[index] - outtemp[index+step]
	      return out/float(N)


	  def FWHT(x):
	      """ Fast Walsh-Hadamard Transform
	      Based on mex function written by Chengbo Li@Rice Uni for his TVAL3 algorithm.
	      His code is according to the K.G. Beauchamp's book -- Applications of Walsh and Related Functions.
	      """
	      x = x.squeeze()
	      N = x.size
	      G = N // 2 # Number of Groups
	      M = 2 # Number of Members in Each Group

	      # First stage
	      y = np.zeros((G,2))
	      y[:,0] = x[0::2] + x[1::2]
	      y[:,1] = x[0::2] - x[1::2]
	      x = y.copy()
	      # Second and further stage
	      for nStage in range(2,int(log(N,2))+1):
	          y = np.zeros((G//2,M*2))
	          y[0:G//2,0:M*2:4] = x[0:G:2,0:M:2] + x[1:G:2,0:M:2]
	          y[0:G//2,1:M*2:4] = x[0:G:2,0:M:2] - x[1:G:2,0:M:2]
	          y[0:G//2,2:M*2:4] = x[0:G:2,1:M:2] - x[1:G:2,1:M:2]
	          y[0:G//2,3:M*2:4] = x[0:G:2,1:M:2] + x[1:G:2,1:M:2]
	          x = y.copy()
	          G = int(G/2)
	          M = M*2
	      x = y[0,:]
	      x = x.reshape((x.size,1))
	      return x/float(N)

	     
	  if __name__ == "__main__":
	      x = np.random.random(1024**2)
	      t1 = clock()
	      y1 = SFWHT(x)
	      t1 = clock() - t1
	      print(t1)
	      t2 = clock()
	      y2 = FWHT(x)
	      t2 = clock() - t2
	      print(t2)
	

GrayCode.py

	  def isOdd(integer):
	      #assert isinstance(integer, int)
	      return integer % 2 == 1

	  def isEven(integer):
	      #assert isinstance(integer, int)
	      return integer % 2 == 0

	  def _list_to_string(li):
	      return ''.join(map(str, li))

	  class GrayCode(object):
	      def __init__(self, nbits):
	          self._nbits = nbits
	          self._grayCode = []
	          self.__generate()

	      def __getitem__(self, i):
	          return self._grayCode[i]

	      def __str__(self):
	          return str(self._grayCode)

	      __repr__ = __str__

	      def __iter__(self):            
	          return self._grayCode.__iter__()

	      def __generate(self):
	          li = [0 for i in range(self._nbits)]
	          self._grayCode.append(_list_to_string(li))

	          for term in range(2, (1<<self._nbits)+1):
	              if isOdd(term):                
	                  for i in range(-1,-(self._nbits),-1):
	                      if li[i]==1:                        
	                          li[i-1]=li[i-1]^1                        
	                          break
	                      
	              if isEven(term):
	                  li[-1]=li[-1]^1

	              self._grayCode.append(_list_to_string(li))

	  class GrayCodeIterator(object):
	      def __init__(self, nbits):
	          self._nbits = nbits

	      def __iter__(self):
	          li = [0 for i in range(self._nbits)]
	          yield _list_to_string(li)

	          for term in range(2, (1<<self._nbits)+1):
	              if isOdd(term):                
	                  for i in range(-1,-(self._nbits),-1):
	                      if li[i]==1:                        
	                          li[i-1]=li[i-1]^1                        
	                          break
	                      
	              if isEven(term):
	                  li[-1]=li[-1]^1

	              yield _list_to_string(li)


	  if __name__=='__main__':
	      d = 4
	      codes=GrayCode(d)
	      print ('%d digits gray codes:', d)
	      print (codes)
	      print ('Using Iterator:')
	      #for c in GrayCode(20):  
	      #    print c
	      for c in GrayCodeIterator(20):
	          print (c)
	

Python 3

	  import FWHT as fwht
	  import GrayCode as gc
	  import numpy as np
	  import importlib
	  importlib.reload(fwht)
	  importlib.reload(gc)
	  
	  a = np.array([19, -1, 11, -9, -7, 13, -15, 5])
	  
	  # Secuency ordered
	  print("Secuency ordered")
	  print(fwht.SFWHT(a))
	  print(fwht.FWHT(a).T)
	  
	  from scipy.linalg import hadamard
	  print(hadamard(4, dtype=complex))
	  print(hadamard(8))
	  # Hadamard ordered
	  print(np.dot(a,hadamard(8))/8)
	  
	  # // division error example
	  print("matrix indice")
	  print(a[0:8//2])
	  print(a[0:8/2])

	  print(np.zeros((8//2,2)))
	  np.zeros(8//2,2)
	
	  Secuency ordered
	  [  2.   3.   0.   4.   0.   0.  10.   0.]
	  [[  2.   3.   0.   4.   0.   0.  10.   0.]]
	  [[ 1.+0.j  1.+0.j  1.+0.j  1.+0.j]
	   [ 1.+0.j -1.-0.j  1.+0.j -1.-0.j]
	   [ 1.+0.j  1.+0.j -1.-0.j -1.-0.j]
	   [ 1.+0.j -1.-0.j -1.-0.j  1.+0.j]]
	  [[ 1  1  1  1  1  1  1  1]
	   [ 1 -1  1 -1  1 -1  1 -1]
	   [ 1  1 -1 -1  1  1 -1 -1]
	   [ 1 -1 -1  1  1 -1 -1  1]
	   [ 1  1  1  1 -1 -1 -1 -1]
	   [ 1 -1  1 -1 -1  1 -1  1]
	   [ 1  1 -1 -1 -1 -1  1  1]
	   [ 1 -1 -1  1 -1  1  1 -1]]
	  [  2.   0.   4.   0.   3.  10.   0.   0.]
	  matrix indice
	  [19 -1 11 -9]

	  ---------------------------------------------------------------------------
	  TypeError Traceback (most recent call last)
	  <ipython-input-194-830b68925cc9> in <module>()
	       22 print("matrix indice")
	       23 print(a[0:8//2])
	  ---> 24 print(a[0:8/2])

	  TypeError: slice indices must be integers or None or have an __index__ method
	
	  print(np.zeros((8//2,2)))
	  np.zeros(8//2,2)
	  
	  np.zeros(8/2,2)
	
	  [[ 0.  0.]
	   [ 0.  0.]
	   [ 0.  0.]
	   [ 0.  0.]]
	  
	  ---------------------------------------------------------------------------
	  TypeError Traceback (most recent call last)
	  <ipython-input-205-d3ad594fc4dc> in <module>()
	        1 print(np.zeros((8//2,2)))
	  ----> 2 np.zeros(8//2,2)
	  
	  TypeError: data type not understood
	  
	  ---------------------------------------------------------------------------
	  TypeError Traceback (most recent call last)
	  <ipython-input-206-805c1441d66f> in <module>()
	  ----> 1 np.zeros(8/2,2)
	  
	  TypeError: 'float' object cannot be interpreted as an integer
	

²èÁüÆÉ¤ß¹þ¤ß¤ä½ñ¤­¹þ¤ß¤ÈÆó¼¡¸µÎ¥»¶¥³¥µ¥¤¥óÊÑ´¹(DCT)

Matlab¤Ë¤Ï¡¢imread¤äimwrite¤¬ÁõÈ÷¤µ¤ì¤Æ¤¤¤ë¤¬¡¢Scilab¤Ç¤Ïɸ½à¾õÂ֤ǻȤ¨¤Ê¤¤¡£6.0.x¤Ç¤Ï Image Processing and Computer Vision (IPCV) Toolbox¤òƳÆþ¤¹¤ë¤È»È¤¨¤ë¤è¤¦¤Ë¤Ê¤ë¡£ 5.x·Ï¤Ç¤ÏÊ̤ÎToolbox(Image_Processing_Toolbox_2 (IPT2) for 5.3.x¡¢ Scilab Image and Video Processing (SIVP) toolbox for 5.5.x) ¤¬Â¸ºß¤·¡¢¥Ð¡¼¥¸¥ç¥ó¤Ë¤è¤Ã¤Æ»È¤¨¤ëToolbox¤¬°Û¤Ê¤ë¤Î¤ÏScilab¤Î·çÅÀ¤Î°ì¤Ä¤Ç¤¢¤ë¡£

¤Þ¤º¤ÏHadamard matrix¤ò²èÁü¤Ë½ñ¤­½Ð¤¹¤Î¤È¡¢²èÁü¤òÆÉ¤ß¹þ¤ó¤ÇÆó¼¡¸µÎ¥»¶¥³¥µ¥¤¥óÊÑ´¹¤ò¹Ô¤Ã¤¿·ë²Ì¤òɽ¼¨¤¹¤ë¤È¤³¤í¤Þ¤Ç¡£¸¶ÅÀÉÕ¶á¤ËÂ礭¤ÊÃͤ¬½¸¤Þ¤Ã¤Æ¤¤¤ë¤Î¤¬¤è¤¯¤ï¤«¤ë¡£

²èÁü¥»¥Ã¥È

Scilab

	  atomsInstall("IPCV")

	  N=256;
	  hadamardMatrix=hadamard(N);

	  function wmat=had2wal(hmat,msize)
	  HadIdx = 0:msize-1;
	  M = log2(msize)+1;
	  binHadIdx = strrev(dec2bin(HadIdx(:),M));
	  binSeqVdx = zeros(msize,M);
	  for k = 1:1:msize
	      binSeqVdx(k,:) = strtod(strsplit(binHadIdx(k)))';
	  end
	  binSeqIdx = zeros(msize,M-1);
	  for k = M:-1:2
	      binSeqIdx(:,k) = bitxor(binSeqVdx(:,k),binSeqVdx(:,k-1));
	  end
	  for k = 1:1:msize
	      HadIdx(k) = bin2dec(strcat(string(binSeqIdx(k,:))));
	  end
	  wmat = hmat(HadIdx+1,:);
	  endfunction
	  
	  walshMatrix = had2wal(hadamardMatrix,N);
	  imwrite(hadamardMatrix,"hmat.bmp");
	  imwrite(walshMatrix,"wmat.bmp");
	  
	  img_orig = double(imread("BRIDGE.bmp"));
	  imshow(uint8(img_orig));
	  surf(imdct(img_orig))
	  surf(imdct(img_orig)(1:50,1:50))
	

hmat.bmp
Hadamard matrix
wmat.bmp
Walsh matrix

bridge.jpg
bridge.jpg
bridge.jpg

Octave

	  img_orig = double(imread("Text.bmp"));
	  imshow(uint8(img_orig));
	  img_dct = dct2(img_orig);
	  surf(img_dct);
	  surf(img_dct(1:50,1:50));
	

bridge.png

bridge.png
bridge.png

Two-Dimensional Hadamard Transform Æó¼¡¸µ¥¢¥À¥Þ¡¼¥ëÊÑ´¹

Æó¼¡¸µFFT¤äÆó¼¡¸µDCT¤ÈƱÍÍ¡¢¹ÔµÚ¤ÓÎ󤽤줾¤ì¤Î£²²óľ¸òÊÑ´¹¤¹¤ì¤Ð¤è¤¤¡£Äã¼þÇȤ«¤é¹â¼þÇȤ˽ç¤Ëʤ٤é¤ì¤¿·¸¿ô¤òÆÀ¤ë¤Ë¤Ï¡¢Sequency Matrix¤ò»È¤¦¤¬¡¢ ¤½¤Î¾¤Î¹ÔÎó¤ò»È¤Ã¤Æ¤âÎɤ¤¡£¹â®¥¢¥À¥Þ¡¼¥ëÊÑ´¹¤Î¤¿¤á¤Ë¤Ï¡¢Natural order°Ê³°¤Ç¤Ï¡¢¾å½Ò¤ÎÄ̤êÆþÎϽç¤ÎÆþ¤ìÂØ¤¨¤¬É¬ÍפǤ¢¤ë¡£

¥¢¥À¥Þ¡¼¥ëÊÑ´¹¤ÈÎ¥»¶¥³¥µ¥¤¥óÊÑ´¹¤Ï¡¢·×¿ô¹ÔÎó·Á¤¬Èæ³ÓŪ»÷¤Æ¤¤¤ë¤À¤±¤À¤¬¡¢Í·¤Ó¤ÇµÕÊÑ´¹¤ò¤½¤ì¤¾¤ìÆþ¤ìÂØ¤¨¤¿´ðÄì¤ò»È¤¦¤È¡¢Á°±Ò·Ý½Ñ¤Î¤è¤¦¤Ê²èÁü¤¬½Ð¤ë¡£

Scilab

	  function imat = fwht2d(imat,hmat)
	  N = sqrt(length(imat))
	  tmat = zeros(N,N);
	  for i = 1:N
	    tmat(i,:) = imat(i,:) * hmat / N;
	  end
	  imat = zeros(N,N);
	  for j = 1:N
	    imat(:,j) = hmat * tmat(:,j)
	  end
	  endfunction
	  
	  a2d = matrix(1:64,8,8)'

	  // Sequency order
	  fwht2d(a2d,walshMatrix)
	  walshMatrix*a2d*walshMatrix / 8
	
	   a2d  = 
	  
	     1.    2.    3.    4.    5.    6.    7.    8. 
	     9.    10.   11.   12.   13.   14.   15.   16.
	     17.   18.   19.   20.   21.   22.   23.   24.
	     25.   26.   27.   28.   29.   30.   31.   32.
	     33.   34.   35.   36.   37.   38.   39.   40.
	     41.   42.   43.   44.   45.   46.   47.   48.
	     49.   50.   51.   52.   53.   54.   55.   56.
	     57.   58.   59.   60.   61.   62.   63.   64.

	   ans  =
	  
	     260.  -16.   0.  -8.   0.   0.   0.  -4.
	    -128.   0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	    -64.    0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	    -32.    0.    0.   0.   0.   0.   0.   0.
	  
	   ans  =
	  
	     260.  -16.   0.  -8.   0.   0.   0.  -4.
	    -128.   0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	    -64.    0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	     0.     0.    0.   0.   0.   0.   0.   0.
	    -32.    0.    0.   0.   0.   0.   0.   0.
	
	  // Ä̾ï¤Ï°ÕÌ£¤Î¤Ê¤¤¹Ô°Ù
	  img_dct = imdct(img_orig);
	  img_wal = fwht2d(img_dct,walshMatrix);
	  imshow(uint8( (img_wal-min(img_wal))/(max(img_wal)-min(img_wal))*255 ));
	  
	  img_mat = fwht2d(img_orig,walshMatrix);
	  img_ict = imidct(img_mat);
	  imshow(uint8( (img_ict-min(img_ict))/(max(img_ict)-min(img_ict))*255 ));
	

bridge_dctht.png
bridge_htdct.png

Reader, suppose you were an idiot.  And suppose you were a member of
Congress.  But I repeat myself.
		-- Mark Twain

Monica [on the phone]: Hey, have you guys eaten, because uh, Richard and I
just finished and we've got leftovers… Chicken and potatoes… What am I
wearing?… Actually, nothing but rubber gloves.

[Chandler and Joey come sprinting in]

Joey: Ya know, one of these times you're gonna really be naked and we're not
gonna come over.

    -- David Crane & Marta Kauffman
    -- "Friends" (T.V. Show) ( http://en.wikipedia.org/wiki/Friends )


Powered by UNIX fortune(6)
[ Main Page ]