Design a 1/f spectrum shaping (pink-noise) filter

% "Filter design" lecture notes (EE364) by S. Boyd
% "FIR filter design via spectral factorization and convex optimization"
% by S.-P. Wu, S. Boyd, and L. Vandenberghe
% (a figure is generated)
%
% Designs a log-Chebychev filter magnitude design given as:
%
%   minimize   max| log|H(w)| - log D(w) |   for w in [0,pi]
%
% where variables are impulse response coefficients h, and data
% is the desired frequency response magnitude D(w).
%
% We can express and solve the log-Chebychev problem above as
%
%   minimize   max( R(w)/D(w)^2, D(w)^2/R(w) )
%       s.t.   R(w) = |H(w)|^2   for w in [0,pi]
%
% where we now use the auto-correlation coeffients r as variables.
%
% As an example we consider the 1/sqrt(w) spectrum shaping filter
% (the so-called pink-noise filter) where D(w) = 1/sqrt(w).
% Here we use a logarithmically sampled freq range w = [0.01*pi,pi].
%
% Written for CVX by Almir Mutapcic 02/02/06

% parameters
n = 40;      % filter order
m = 15*n;    % frequency discretization (rule-of-thumb)

% log-space frequency specification
wa = 0.01*pi; wb = pi;
wl = logspace(log10(wa),log10(wb),m)';

% desired frequency response (pink-noise filter)
D = 1./sqrt(wl);

% matrix of cosines to compute the power spectrum
Al = [ones(m,1) 2*cos(kron(wl,[1:n-1]))];

% solve the problem using cvx
cvx_begin
  variable r(n,1)   % auto-correlation coefficients
  variable R(m,1)   % power spectrum

  % log-chebychev minimax design
  minimize( max( max( [R./(D.^2)  (D.^2).*inv_pos(R)]' ) ) )
  subject to
     % power spectrum constraint
     R == Al*r;
cvx_end

% check if problem was successfully solved
disp(['Problem is ' cvx_status])
if ~strcmp(cvx_status,'Solved')
  return
end

% spectral factorization
h = spectral_fact(r);

% figures
figure(1)
H = exp(-j*kron(wl,[0:n-1]))*h;
loglog(wl,abs(H),wl,D,'r--')
set(gca,'XLim',[wa pi])
xlabel('freq w')
ylabel('mag H(w) and D(w)')
legend('optimized','desired')
 
Calling SeDuMi: 2440 variables (40 free), 2399 equality constraints
------------------------------------------------------------------------
SeDuMi 1.1 by AdvOL, 2005 and Jos F. Sturm, 1998, 2001-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
Split 40 free variables
eqs m = 2399, order n = 1881, dim = 3081, blocks = 601
nnz(A) = 52797 + 0, nnz(ADA) = 730789, nnz(L) = 545695
 it :     b*y       gap    delta  rate   t/tP*  t/tD*   feas cg cg  prec
  0 :            3.01E-001 0.000
  1 :  1.04E+002 1.19E-001 0.000 0.3938 0.9000 0.9000  -0.99  1  1  6.3E+001
  2 :  7.68E+002 2.16E-002 0.000 0.1820 0.9000 0.9000  -0.97  1  1  5.7E+001
  3 :  1.78E+003 7.55E-004 0.000 0.0350 0.9900 0.9900  -0.60  1  1  7.0E+000
  4 :  1.36E+002 5.31E-005 0.000 0.0703 0.9900 0.9900   1.08  1  1  4.5E-001
  5 :  2.15E+001 2.05E-005 0.000 0.3864 0.9000 0.9000   6.70  1  1  2.9E-002
  6 :  5.76E+000 9.22E-006 0.000 0.4497 0.9000 0.9000   4.66  1  1  4.0E-003
  7 :  2.00E+000 3.01E-006 0.000 0.3269 0.9000 0.9000   2.35  1  1  8.2E-004
  8 :  1.52E+000 1.42E-006 0.000 0.4721 0.9000 0.9000   1.08  1  1  3.9E-004
  9 :  1.31E+000 6.61E-007 0.000 0.4648 0.9000 0.9000   0.93  1  1  1.9E-004
 10 :  1.22E+000 3.22E-007 0.000 0.4873 0.9000 0.9000   0.93  1  1  9.2E-005
 11 :  1.21E+000 1.60E-007 0.000 0.4975 0.9000 0.9000   1.01  1  1  4.5E-005
 12 :  1.21E+000 2.09E-009 0.000 0.0131 0.9000 0.0000   1.00  1  1  1.5E-005
 13 :  1.20E+000 7.99E-011 0.000 0.0382 0.9257 0.9000   1.00  1  1  1.7E-006
 14 :  1.19E+000 1.86E-011 0.000 0.2329 0.9166 0.9000   1.00  1  1  5.0E-007
 15 :  1.19E+000 4.69E-012 0.000 0.2522 0.9000 0.6412   1.00  2  2  1.6E-007
 16 :  1.19E+000 5.99E-013 0.000 0.1276 0.9123 0.9000   1.00  2  2  2.7E-008
 17 :  1.19E+000 3.88E-014 0.000 0.0647 0.9900 0.9721   1.00  2  2  1.3E-009

iter seconds digits       c*x               b*y
 17     45.5   Inf  1.1873326627e+000  1.1873409079e+000
|Ax-b| =  1.7e-008, [Ay-c]_+ =  9.3E-009, |x|= 2.7e+002, |y|= 9.8e-001

Detailed timing (sec)
   Pre          IPM          Post
3.856E+000    4.555E+001    0.000E+000    
Max-norms: ||b||=1, ||c|| = 3.183099e+001,
Cholesky |add|=0, |skip| = 0, ||L.L|| = 141.492.
------------------------------------------------------------------------
Status: Solved
Optimal value (cvx_optval): +1.18733
Problem is Solved