Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

How can the v9.0 built-in Spectrogram[list, n, d] function be modified to accept complex exponential functions?

The V8.0.4 code that produces the result I'm looking for follows. How do I adapt v9.0 to do the same thing?

*************
(* Spectrogram of complex exponentials using MMA_ 8.0.4 *)
Clear[se, \
fs, \[CapitalDelta]T, n]; se[amp_, f_] := amp*Exp[2 \[Pi] I f t]
fs = 100 ; \[CapitalDelta]T = 130 ; \[CapitalDelta]t = N[1/fs]; n = 
 fs*\[CapitalDelta]T; \[CapitalDelta]f = 
 N[1/(2 \[CapitalDelta]T)] ; fmax = N[1/(2 \[CapitalDelta]t)];
Clear[f1, f2, f3]; f1 = 10; f2 = 20; f3 = -13; 
cs1 = N[Table[
   se[1, f1] , {t, 0, \[CapitalDelta]T, \[CapitalDelta]t}] ]; cs1 = 
 Most[cs1];
cs2 = N[Table[
   se[1, f2] , {t, 0, \[CapitalDelta]T, \[CapitalDelta]t}] ]; cs2 = 
 Most[cs2];
cs3 = N[Table[
   se[1, f3] , {t, 0, \[CapitalDelta]T, \[CapitalDelta]t}] ]; cs3 = 
 Most[cs3];
w1 = Table[
  1, {4000}];  Length[w1]; (* rectangular window *)
Length[cs1] ;
w1ls = ArrayPad[w1, {0, Length[cs1] - Length[w1]} ]; Length[w1ls] ;
wcs1 = w1ls*cs1; Length[wcs1];
ListLinePlot[Re[wcs1], Frame -> True, PlotRange -> All, 
  PlotStyle -> Blue, ImageSize -> 250];
w2 = Table[1, {4000}]; Length[w2];
Length[cs2];
w2ls = ArrayPad[
  w2, {Length[w1] + 1 , ( 
    Length[cs2] - Length[w1] - 1 - Length[w2])  }]; Length[w2ls];
wcs2 = w2ls*cs2; Length[wcs2];
ListLinePlot[Re[wcs2], Frame -> True, PlotRange -> All, 
  PlotStyle -> Green, ImageSize -> 250];
w3 = Table[1, {5000}]; Length[w3];
Length[cs3] ;
w3ls = ArrayPad[
  w3, { (Length[w1] + 1 + Length[w2] + 1), ( 
    Length[cs3] - Length[w1] - Length[w2] - 1 - Length[w3] - 
     1 )}];  Length[w3ls];
wcs3 = w3ls*cs3; Length[wcs3];
(********)
Clear[in]; in = 
 wcs1 + wcs2 + 
  wcs3 ;(* Composite Complex Signal *)
(********)
(* Set up STFT \
parameters *)
ns = 100 ;(*specify # samples/segment*)
insegs = 
 Partition[in, ns, 1, {1, 1}];
finsegs = 
  Chop[Fourier[#, FourierParameters -> {-1, -1}] ] & /@ insegs; 
ffinsegs = Abs[finsegs]^2;
rffinsegs = RotateRight[#, (ns/2) - 1] & /@ ffinsegs; 
p = ArrayPlot[Transpose[rffinsegs], DataReversed -> True,
  FrameTicks -> 
   {   { { { 
       0, - 5*fmax/5}, {ns*(1/10), -4*fmax/5}, {ns*(2/10), -3*fmax/5},
       {ns*(3/10), -2*fmax/5}, {ns*(4/10), -1*fmax/5},
      {ns*(5/10), 0}, {ns*(6/10), fmax/5}, {ns*(7/10), 
       2*fmax/5}, {ns*(8/10), 3*fmax/5 }, {ns*(9/10), 
       4*fmax/5}, {ns*(10/10), 5*fmax/5 "Hz"} }, None } ,
      { {{1000, 10}, {2000, 20}, {3000, 30}, {4000, 40}, {5000, 
       50}, {6000, 60}, {7000, 70}, {8000, 80}, {9000, 90}, {10000, 
       100}, {11000, 110}, {12000, 120}, {13000, 130 "sec"} }, 
     None }  },
   AspectRatio -> 1/3 , ImageSize -> 650 , 
  BaseStyle -> {FontFamily -> "Arial", FontWeight -> Bold, 12}]

(* MMA_ 9.0: Using built-in command < Spectrogram[list,n,d] > *)

Spectrogram[in, 100, 1]
Spectrogram[Re[in], 100, 1]
share|improve this question
add comment

1 Answer

Could you try this?

Unprotect[Evaluate@Spectrogram];
PrependTo[DownValues@Spectrogram, 
  HoldPattern@
    Spectrogram[l : {___, _Complex, ___}, 
     n : (_Integer | Automatic) : Automatic, 
     m : (_Integer | Automatic) : Automatic, OptionsPattern[]] :> 
   Spectrogram[Re@InverseFourier@PadRight[Fourier@l, 2 Length@l, 0`], 
    If[n === Automatic, ## &[], 2 n], 
    If[m === Automatic, ## &[], 2 m], 
    SampleRate :> 
     If[OptionValue[SampleRate] === Automatic, Automatic, 
      2 OptionValue[SampleRate]]]];
Protect[Spectrogram];

So if

Spectrogram[Table[Cos[ i/4 + (i/20)^2], {i, 2000}], SampleRate -> 10]

gives

Mathematica graphics

then

Spectrogram[Table[Cos[ i/4 + (i/20)^2], {i, 2000}] + 0.01 I, 
 SampleRate -> 10]

gives

Mathematica graphics

share|improve this answer
    
I honestly couldn't test it much or try your code but I figure you want it to work like Matlab's, where if complex, the full spectrum is shown. I'll be back in some minutes and delete this if it doesn't work as intended –  Rojo Feb 4 '13 at 9:35
    
Thanks for the hint. I find that using your mod results in a disparity between the window size (that seems to be locked at 2) and the desired partition size, 100 in my case. Any ideas? –  stqnt Feb 6 '13 at 16:00
    
Oh, yeah, sorry about that @stqnt. I double the points so probably n and d should be doubled too? Check it, I'll edit now –  Rojo Feb 6 '13 at 19:11
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.