/
selectQESL.m
executable file
·155 lines (147 loc) · 3.68 KB
/
selectQESL.m
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
function sv = selectQESL(v,sy)
%sv = selectQESL(v,sy) Select the elements of a 2*M-element DAC
%to minimize the selection error, subject to the constraint that
%the number of elements allocated to [Ip In Qp Qn ]
%is n= [(M+real(v))/2 (M-real(v))/2 (M+imag(v))/2 (M-imag(v))/2].
%As a result of these constraints, sum(sy)=v and M elements are
%allocated to I and Q at all times.
% See ADI Notebook #17, pages 22 & 24
sy = sy(:);
M = length(sy)/2;
n = zeros(1,4);
n(1) = (M+real(v))/2; n(3) = (M+imag(v))/2;
n(2) = M-n(1); n(4) = M-n(3);
if any(n<0)
error('v argument is out of range');
end
sv = zeros(2*M,1);
%Sort the desired usage by real and imaginary parts
[iList iInd] = sort(real(sy));
[qList qInd] = sort(imag(sy));
%Pad the lists with +/-Inf to allow indices to run off the ends
iList = [-Inf; iList; Inf]; iInd = [0; iInd; 0];
qList = [-Inf; qList; Inf]; qInd = [0; qInd; 0];
% Walk through the lists, top-to-bottom (-I,-Q) and bottom-to-top (+I,+Q),
% allocating elements according to the desired usage,
% if needed for that purpose.
i1 = 2; i2 = 2*M+1;
q1 = 2; q2 = 2*M+1;
[preference mi] = max( [iList(i2) -iList(i1) qList(q2) -qList(q1)] );
while preference>=0
% Determine which element has highest desired usage
% Use that element the way it wants to be used, if it is needed there.
% If an element is used, remove it from the lists.
% Then move on to the next element on the list.
i = 0; q = 0;
switch mi
case 1 % +I
if n(1)>0
sv(iInd(i2)) = 1;
n(1) = n(1)-1;
i = i2;
q = find(qInd == iInd(i));
end
i2 = i2-1;
case 2 % -I
if n(2)>0
sv(iInd(i1)) = -1;
n(2) = n(2)-1;
i = i1;
q = find(qInd == iInd(i));
end
i1 = i1+1;
case 3 % +Q
if n(3)>0
sv(qInd(q2)) = 1j;
n(3) = n(3)-1;
q = q2;
i = find(iInd == qInd(q));
end
q2 = q2-1;
case 4 % -Q
if n(4)>0
sv(qInd(q1)) = -1j;
n(4) = n(4)-1;
q = q1;
i = find(iInd == qInd(q));
end
q1 = q1+1;
end
if i % Delete the chosen element from the lists
iList = iList([1:i-1 i+1:end]);
iInd = iInd([1:i-1 i+1:end]);
qList = qList([1:q-1 q+1:end]);
qInd = qInd([1:q-1 q+1:end]);
if i1>i; i1=i1-1; end
if i2>=i; i2=i2-1; end
if q1>q; q1=q1-1; end
if q2>=q; q2=q2-1; end
end
if q2<q1 & i2<i1
preference = -1;
else
[preference mi] = max( [iList(i2) -iList(i1) qList(q2) -qList(q1)] );
end
end
% Now that elements have been allocated the way they prefer to be,
% two of the constraints should be satisfied
if n(1)+n(2)>0 & n(3)+n(4)>0 % Two constraints not satisfied
% A trade-off is needed
if n(1)
ni = 1;
i_val = 1;
iList = -iList;
else
ni = 2;
i_val = -1;
iList = iList(end:-1:1);
iInd = iInd(end:-1:1);
end
if n(3)
nq = 3;
q_val = 1j;
qList = -qList;
else
nq = 4;
q_val = -1j;
qList = qList(end:-1:1);
qInd = qInd(end:-1:1);
end
% Examine elements in the iList and qList
i1 = 2; q1 = 2;
while n(1)+n(2)>0 & n(3)+n(4)>0
if iList(i1) > qList(q1)
% Assign the element to Q
sv(iInd(i1)) = q_val;
n(nq) = n(nq) -1;
i = i1;
q = find(qInd == iInd(i));
else
% Assign the element to I
sv(qInd(i1)) = i_val;
n(ni) = n(ni) -1;
q = q1;
i = find(iInd == qInd(q));
end
% Delete the chosen element from the lists
iList = iList([1:i-1 i+1:end]);
iInd = iInd([1:i-1 i+1:end]);
qList = qList([1:q-1 q+1:end]);
qInd = qInd([1:q-1 q+1:end]);
if i1>i; i1=i1-1; end
if q1>q; q1=q1-1; end
end
end
% Three constraints should be satisfied.
% Just assign remaining elements where they are needed
ind = iInd( find(iInd ~=0) );
if n(1)
sv(ind) = 1;
elseif n(2)
sv(ind) = -1;
elseif n(3)
sv(ind) = 1j;
elseif n(4)
sv(ind) = -1j;
end
return