function A = smat(v,blk)
% SMAT   converts a vector of length sum_i  blk(i)*(blk(i)+1)/2,
%        (sum over # blocks) to a n by n symmetric matrix, where
%        n = sum_i blk(i)
%
% A = smat(v,blk)
%
%   Note: smat returns a sparse matrix if either the length of blk
%   is > 1, i.e. there are more than one block, or if the vector v
%   is itself sparse, i.e. the block(s) is(are) sparse.
%
% input variables:
%     - v         the vector representation of a block diagonal symmetric matrix
%     - blk       block structure vector
%
% output variables:
%     - A         the block diagonal symmetric matrix

% Version 0.92 BETA
% Copyright (c) 1997 by
% J.-P. Haeberly, M. Nayakkankuppam, M.L. Overton
% Last modified: 9/3/97
%
 nblk = length(blk);
 n = sum(blk);
 dim = size(v);
 if dim(2) > dim(1), v = v'; end;
%
 ir2 = 1.0/sqrt(2);
 if nblk > 1 | issparse(v),
    A = sparse(n,n);
 else,
    A = zeros(n,n);
 end;
 start = 1; fin = 0;
 vstart = 1; vfin = 0;
 for bidx = 1:nblk,
    bsize = blk(bidx);
    b2size = bsize*(bsize+1)/2;
    fin = fin + bsize;
    vfin = vfin + b2size;
    block = zeros(bsize);
    J = (1:bsize)';
    J = J(:,ones(1,bsize));
    I = J';
    block(I<=J) = v(vstart:vfin);
    A(start:fin,start:fin) = block;
    start = start + bsize;
    vstart = vstart + b2size;
 end;   % bidx loop
%
 d = diag(A);   % save the old diagonal
 A = A - diag(d);  % A's diagonal elts are now zero
 A = ir2*A;
 A = A + A';
 A = A + diag(d);   % restore diagonal elts
%
% END function
