<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/cnxml/0.5/DTD/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="new0">
  <name xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">DWT Implementation using FFTs</name>
  <metadata xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">
  <md:version xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">2.0</md:version>
  <md:created xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">2003/01/13</md:created>
  <md:revised xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">2003/01/13</md:revised>
  <md:authorlist xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">
      <md:author xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="schniter">
      <md:firstname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Phil</md:firstname>
      
      <md:surname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Schniter</md:surname>
      <md:email xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">schniter@ee.eng.ohio-state.edu</md:email>
    </md:author>
  </md:authorlist>

  <md:maintainerlist xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">
    <md:maintainer xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="charlet">
      <md:firstname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Charlet</md:firstname>
      
      <md:surname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Reedstrom</md:surname>
      <md:email xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">charlet@rice.edu</md:email>
    </md:maintainer>
    <md:maintainer xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="schniter">
      <md:firstname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Phil</md:firstname>
      
      <md:surname xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">Schniter</md:surname>
      <md:email xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">schniter@ee.eng.ohio-state.edu</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">
    <md:keyword xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">circular convolution</md:keyword>
    <md:keyword xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">DWT</md:keyword>
  </md:keywordlist>

  <md:abstract xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/"/>
</metadata>



  <content xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">
      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para9">
	Finally, we say a few words about DWT implementation.  Here
	we focus on a single DWT stage and assume circular
	convolution, yielding an
	<m:math><m:ci>M</m:ci></m:math>x<m:math><m:ci>M</m:ci></m:math>
	DWT matrix 
	<m:math>
	  <m:ci type="matrix"><m:msub> 
	      <m:mi>T</m:mi> 
	      <m:mi>M</m:mi>
	    </m:msub></m:ci> 
	</m:math>
	.  In the general case,
	<m:math><m:ci>M</m:ci></m:math>x<m:math><m:ci>M</m:ci></m:math>
	matrix multiplication requires 
	<m:math>
	  <m:apply>
	    <m:power/>
	    <m:ci>M</m:ci>
	    <m:cn>2</m:cn>
	  </m:apply>
	</m:math> multiplications.  The DWT matrices, however, have
	a circular-convolution structure which allows us to
	implement them using significantly less multiplies.  Below
	we present some simple and reasonably efficient approaches
	for the implementation of 
	<m:math>
	  <m:ci type="matrix"><m:msub> 
	      <m:mi>T</m:mi> 
	      <m:mi>M</m:mi>
	    </m:msub></m:ci> 
	</m:math> and 
	<m:math>
	  <m:apply>
	    <m:transpose/>
	    <m:ci type="matrix"><m:msub> 
		<m:mi>T</m:mi> 
		<m:mi>M</m:mi>
	      </m:msub></m:ci>
	  </m:apply>
	</m:math>.
      </para>

      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para10">
	We treat the inverse DWT first.  Recall that in the lowpass
	synthesis branch, we upsample the input before circularly
	convolving with
	<m:math>
	  <m:apply>
	    <m:ci type="fn">H</m:ci>
	    <m:ci>z</m:ci>
	  </m:apply>
	</m:math>.  Denoting the upsampled coefficient sequence by 
	<m:math>
	  <m:apply>
	    <m:ci type="fn" class="discrete">a</m:ci>
	    <m:ci>n</m:ci>
	  </m:apply>
	</m:math>, fast circular convolution 
	<m:math>
	  <m:apply>
	    <m:csymbol definitionURL="http://cnx.rice.edu/cd/cnxmath.ocd#convolve"/>
	    <m:apply>
	      <m:ci type="fn" class="discrete">a</m:ci>
	      <m:ci>n</m:ci>
	    </m:apply>
	    <m:apply>
	      <m:ci type="fn" class="discrete">h</m:ci>
	      <m:ci>n</m:ci>
	    </m:apply>
	  </m:apply>
	</m:math> can be described as follows (using Matlab
	notation)
      </para>
      <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" type="block">
	ifft( fft(a).*fft(h,length(a)) )
      </code>
      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para11">
	where we have assumed that <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">length(a) ≥
	  length(h)</code>. <note xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" type="footnote">When
	  implementing the multi-level transform, you must ensure that
	  the data length does not become shorter than the filter
	  length!</note>  The highpass branch is handled
	similarly using 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">G</m:ci>
	    <m:ci>z</m:ci>
	  </m:apply>
	</m:math>, after which the two branch outputs are summed.
      </para>

      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para12">
	Next we treat the forward DWT.  Recall that in the lowpass
	analysis branch, we circularly convolve the input with 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">H</m:ci>
	    <m:apply>
	      <m:inverse/>
	      <m:ci>z</m:ci>
	    </m:apply>
	  </m:apply>
	</m:math> and then downsample the result.  The fast circular
	convolution 
	<m:math>
	  <m:apply>
	    <m:csymbol definitionURL="http://cnx.rice.edu/cd/cnxmath.ocd#convolve"/>
	    <m:apply>
	      <m:ci type="fn" class="discrete">a</m:ci>
	      <m:ci>n</m:ci>
	    </m:apply>
	    <m:apply>
	      <m:ci type="fn" class="discrete">h</m:ci>
	      <m:apply>
		<m:minus/>
		<m:ci>n</m:ci>
	      </m:apply>
	    </m:apply>
	  </m:apply>
	</m:math> can be implemented using
      </para>
      <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" type="block">
	<![CDATA[wshift('1', ifft(fft(a).*fft(flipud(h),length(a))), length(h)-1 )]]>
      </code>

      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para13">
	where <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">wshift</code> accomplishes a circular
	shift of the <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">ifft</code> output that makes up
	for the unwanted delay of <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">length(h)-1</code>
	samples imposed by the <code xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/">flipud</code> operation.
	The highpass branch is handled similarly but with filter
	<m:math>
	  <m:apply>
	    <m:ci type="fn">G</m:ci>
	    <m:apply>
	      <m:inverse/>
	      <m:ci>z</m:ci>
	    </m:apply>
	  </m:apply>
	</m:math>.  Finally, each branch is downsampled by factor two.
      </para>

      <para xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="para14">
	We note that the proposed approach is not totally efficient
	because downsampling is performed after circular convolution
	(and upsampling before circular convolution).  Still, we have
	outlined this approach because it is easy to understand and
	still results in major saving when
	<m:math><m:ci>M</m:ci></m:math> is large: it converts the 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">O</m:ci>
	    <m:apply>
	      <m:power/>
	      <m:ci>M</m:ci>
	      <m:cn>2</m:cn>
	    </m:apply>
	  </m:apply>
	</m:math> matrix multiply into an 
	<m:math>
	  <m:apply>
	    <m:ci type="fn">O</m:ci>
	    <m:apply>
	      <m:times/>
	      <m:ci>M</m:ci>
	      <m:apply>
		<m:log/>
		<m:logbase>
		  <m:cn>2</m:cn>
		</m:logbase>
		<m:ci>M</m:ci>
	      </m:apply>
	    </m:apply>
	  </m:apply>
	</m:math> operation.
      </para>
  </content>
  
</document>
