alpar@1
|
1 |
/* glpios04.c (operations on sparse vectors) */
|
alpar@1
|
2 |
|
alpar@1
|
3 |
/***********************************************************************
|
alpar@1
|
4 |
* This code is part of GLPK (GNU Linear Programming Kit).
|
alpar@1
|
5 |
*
|
alpar@1
|
6 |
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
alpar@1
|
7 |
* 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
|
alpar@1
|
8 |
* Moscow Aviation Institute, Moscow, Russia. All rights reserved.
|
alpar@1
|
9 |
* E-mail: <mao@gnu.org>.
|
alpar@1
|
10 |
*
|
alpar@1
|
11 |
* GLPK is free software: you can redistribute it and/or modify it
|
alpar@1
|
12 |
* under the terms of the GNU General Public License as published by
|
alpar@1
|
13 |
* the Free Software Foundation, either version 3 of the License, or
|
alpar@1
|
14 |
* (at your option) any later version.
|
alpar@1
|
15 |
*
|
alpar@1
|
16 |
* GLPK is distributed in the hope that it will be useful, but WITHOUT
|
alpar@1
|
17 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
alpar@1
|
18 |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
alpar@1
|
19 |
* License for more details.
|
alpar@1
|
20 |
*
|
alpar@1
|
21 |
* You should have received a copy of the GNU General Public License
|
alpar@1
|
22 |
* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
|
alpar@1
|
23 |
***********************************************************************/
|
alpar@1
|
24 |
|
alpar@1
|
25 |
#include "glpios.h"
|
alpar@1
|
26 |
|
alpar@1
|
27 |
/***********************************************************************
|
alpar@1
|
28 |
* NAME
|
alpar@1
|
29 |
*
|
alpar@1
|
30 |
* ios_create_vec - create sparse vector
|
alpar@1
|
31 |
*
|
alpar@1
|
32 |
* SYNOPSIS
|
alpar@1
|
33 |
*
|
alpar@1
|
34 |
* #include "glpios.h"
|
alpar@1
|
35 |
* IOSVEC *ios_create_vec(int n);
|
alpar@1
|
36 |
*
|
alpar@1
|
37 |
* DESCRIPTION
|
alpar@1
|
38 |
*
|
alpar@1
|
39 |
* The routine ios_create_vec creates a sparse vector of dimension n,
|
alpar@1
|
40 |
* which initially is a null vector.
|
alpar@1
|
41 |
*
|
alpar@1
|
42 |
* RETURNS
|
alpar@1
|
43 |
*
|
alpar@1
|
44 |
* The routine returns a pointer to the vector created. */
|
alpar@1
|
45 |
|
alpar@1
|
46 |
IOSVEC *ios_create_vec(int n)
|
alpar@1
|
47 |
{ IOSVEC *v;
|
alpar@1
|
48 |
xassert(n >= 0);
|
alpar@1
|
49 |
v = xmalloc(sizeof(IOSVEC));
|
alpar@1
|
50 |
v->n = n;
|
alpar@1
|
51 |
v->nnz = 0;
|
alpar@1
|
52 |
v->pos = xcalloc(1+n, sizeof(int));
|
alpar@1
|
53 |
memset(&v->pos[1], 0, n * sizeof(int));
|
alpar@1
|
54 |
v->ind = xcalloc(1+n, sizeof(int));
|
alpar@1
|
55 |
v->val = xcalloc(1+n, sizeof(double));
|
alpar@1
|
56 |
return v;
|
alpar@1
|
57 |
}
|
alpar@1
|
58 |
|
alpar@1
|
59 |
/***********************************************************************
|
alpar@1
|
60 |
* NAME
|
alpar@1
|
61 |
*
|
alpar@1
|
62 |
* ios_check_vec - check that sparse vector has correct representation
|
alpar@1
|
63 |
*
|
alpar@1
|
64 |
* SYNOPSIS
|
alpar@1
|
65 |
*
|
alpar@1
|
66 |
* #include "glpios.h"
|
alpar@1
|
67 |
* void ios_check_vec(IOSVEC *v);
|
alpar@1
|
68 |
*
|
alpar@1
|
69 |
* DESCRIPTION
|
alpar@1
|
70 |
*
|
alpar@1
|
71 |
* The routine ios_check_vec checks that a sparse vector specified by
|
alpar@1
|
72 |
* the parameter v has correct representation.
|
alpar@1
|
73 |
*
|
alpar@1
|
74 |
* NOTE
|
alpar@1
|
75 |
*
|
alpar@1
|
76 |
* Complexity of this operation is O(n). */
|
alpar@1
|
77 |
|
alpar@1
|
78 |
void ios_check_vec(IOSVEC *v)
|
alpar@1
|
79 |
{ int j, k, nnz;
|
alpar@1
|
80 |
xassert(v->n >= 0);
|
alpar@1
|
81 |
nnz = 0;
|
alpar@1
|
82 |
for (j = v->n; j >= 1; j--)
|
alpar@1
|
83 |
{ k = v->pos[j];
|
alpar@1
|
84 |
xassert(0 <= k && k <= v->nnz);
|
alpar@1
|
85 |
if (k != 0)
|
alpar@1
|
86 |
{ xassert(v->ind[k] == j);
|
alpar@1
|
87 |
nnz++;
|
alpar@1
|
88 |
}
|
alpar@1
|
89 |
}
|
alpar@1
|
90 |
xassert(v->nnz == nnz);
|
alpar@1
|
91 |
return;
|
alpar@1
|
92 |
}
|
alpar@1
|
93 |
|
alpar@1
|
94 |
/***********************************************************************
|
alpar@1
|
95 |
* NAME
|
alpar@1
|
96 |
*
|
alpar@1
|
97 |
* ios_get_vj - retrieve component of sparse vector
|
alpar@1
|
98 |
*
|
alpar@1
|
99 |
* SYNOPSIS
|
alpar@1
|
100 |
*
|
alpar@1
|
101 |
* #include "glpios.h"
|
alpar@1
|
102 |
* double ios_get_vj(IOSVEC *v, int j);
|
alpar@1
|
103 |
*
|
alpar@1
|
104 |
* RETURNS
|
alpar@1
|
105 |
*
|
alpar@1
|
106 |
* The routine ios_get_vj returns j-th component of a sparse vector
|
alpar@1
|
107 |
* specified by the parameter v. */
|
alpar@1
|
108 |
|
alpar@1
|
109 |
double ios_get_vj(IOSVEC *v, int j)
|
alpar@1
|
110 |
{ int k;
|
alpar@1
|
111 |
xassert(1 <= j && j <= v->n);
|
alpar@1
|
112 |
k = v->pos[j];
|
alpar@1
|
113 |
xassert(0 <= k && k <= v->nnz);
|
alpar@1
|
114 |
return (k == 0 ? 0.0 : v->val[k]);
|
alpar@1
|
115 |
}
|
alpar@1
|
116 |
|
alpar@1
|
117 |
/***********************************************************************
|
alpar@1
|
118 |
* NAME
|
alpar@1
|
119 |
*
|
alpar@1
|
120 |
* ios_set_vj - set/change component of sparse vector
|
alpar@1
|
121 |
*
|
alpar@1
|
122 |
* SYNOPSIS
|
alpar@1
|
123 |
*
|
alpar@1
|
124 |
* #include "glpios.h"
|
alpar@1
|
125 |
* void ios_set_vj(IOSVEC *v, int j, double val);
|
alpar@1
|
126 |
*
|
alpar@1
|
127 |
* DESCRIPTION
|
alpar@1
|
128 |
*
|
alpar@1
|
129 |
* The routine ios_set_vj assigns val to j-th component of a sparse
|
alpar@1
|
130 |
* vector specified by the parameter v. */
|
alpar@1
|
131 |
|
alpar@1
|
132 |
void ios_set_vj(IOSVEC *v, int j, double val)
|
alpar@1
|
133 |
{ int k;
|
alpar@1
|
134 |
xassert(1 <= j && j <= v->n);
|
alpar@1
|
135 |
k = v->pos[j];
|
alpar@1
|
136 |
if (val == 0.0)
|
alpar@1
|
137 |
{ if (k != 0)
|
alpar@1
|
138 |
{ /* remove j-th component */
|
alpar@1
|
139 |
v->pos[j] = 0;
|
alpar@1
|
140 |
if (k < v->nnz)
|
alpar@1
|
141 |
{ v->pos[v->ind[v->nnz]] = k;
|
alpar@1
|
142 |
v->ind[k] = v->ind[v->nnz];
|
alpar@1
|
143 |
v->val[k] = v->val[v->nnz];
|
alpar@1
|
144 |
}
|
alpar@1
|
145 |
v->nnz--;
|
alpar@1
|
146 |
}
|
alpar@1
|
147 |
}
|
alpar@1
|
148 |
else
|
alpar@1
|
149 |
{ if (k == 0)
|
alpar@1
|
150 |
{ /* create j-th component */
|
alpar@1
|
151 |
k = ++(v->nnz);
|
alpar@1
|
152 |
v->pos[j] = k;
|
alpar@1
|
153 |
v->ind[k] = j;
|
alpar@1
|
154 |
}
|
alpar@1
|
155 |
v->val[k] = val;
|
alpar@1
|
156 |
}
|
alpar@1
|
157 |
return;
|
alpar@1
|
158 |
}
|
alpar@1
|
159 |
|
alpar@1
|
160 |
/***********************************************************************
|
alpar@1
|
161 |
* NAME
|
alpar@1
|
162 |
*
|
alpar@1
|
163 |
* ios_clear_vec - set all components of sparse vector to zero
|
alpar@1
|
164 |
*
|
alpar@1
|
165 |
* SYNOPSIS
|
alpar@1
|
166 |
*
|
alpar@1
|
167 |
* #include "glpios.h"
|
alpar@1
|
168 |
* void ios_clear_vec(IOSVEC *v);
|
alpar@1
|
169 |
*
|
alpar@1
|
170 |
* DESCRIPTION
|
alpar@1
|
171 |
*
|
alpar@1
|
172 |
* The routine ios_clear_vec sets all components of a sparse vector
|
alpar@1
|
173 |
* specified by the parameter v to zero. */
|
alpar@1
|
174 |
|
alpar@1
|
175 |
void ios_clear_vec(IOSVEC *v)
|
alpar@1
|
176 |
{ int k;
|
alpar@1
|
177 |
for (k = 1; k <= v->nnz; k++)
|
alpar@1
|
178 |
v->pos[v->ind[k]] = 0;
|
alpar@1
|
179 |
v->nnz = 0;
|
alpar@1
|
180 |
return;
|
alpar@1
|
181 |
}
|
alpar@1
|
182 |
|
alpar@1
|
183 |
/***********************************************************************
|
alpar@1
|
184 |
* NAME
|
alpar@1
|
185 |
*
|
alpar@1
|
186 |
* ios_clean_vec - remove zero or small components from sparse vector
|
alpar@1
|
187 |
*
|
alpar@1
|
188 |
* SYNOPSIS
|
alpar@1
|
189 |
*
|
alpar@1
|
190 |
* #include "glpios.h"
|
alpar@1
|
191 |
* void ios_clean_vec(IOSVEC *v, double eps);
|
alpar@1
|
192 |
*
|
alpar@1
|
193 |
* DESCRIPTION
|
alpar@1
|
194 |
*
|
alpar@1
|
195 |
* The routine ios_clean_vec removes zero components and components
|
alpar@1
|
196 |
* whose magnitude is less than eps from a sparse vector specified by
|
alpar@1
|
197 |
* the parameter v. If eps is 0.0, only zero components are removed. */
|
alpar@1
|
198 |
|
alpar@1
|
199 |
void ios_clean_vec(IOSVEC *v, double eps)
|
alpar@1
|
200 |
{ int k, nnz;
|
alpar@1
|
201 |
nnz = 0;
|
alpar@1
|
202 |
for (k = 1; k <= v->nnz; k++)
|
alpar@1
|
203 |
{ if (fabs(v->val[k]) == 0.0 || fabs(v->val[k]) < eps)
|
alpar@1
|
204 |
{ /* remove component */
|
alpar@1
|
205 |
v->pos[v->ind[k]] = 0;
|
alpar@1
|
206 |
}
|
alpar@1
|
207 |
else
|
alpar@1
|
208 |
{ /* keep component */
|
alpar@1
|
209 |
nnz++;
|
alpar@1
|
210 |
v->pos[v->ind[k]] = nnz;
|
alpar@1
|
211 |
v->ind[nnz] = v->ind[k];
|
alpar@1
|
212 |
v->val[nnz] = v->val[k];
|
alpar@1
|
213 |
}
|
alpar@1
|
214 |
}
|
alpar@1
|
215 |
v->nnz = nnz;
|
alpar@1
|
216 |
return;
|
alpar@1
|
217 |
}
|
alpar@1
|
218 |
|
alpar@1
|
219 |
/***********************************************************************
|
alpar@1
|
220 |
* NAME
|
alpar@1
|
221 |
*
|
alpar@1
|
222 |
* ios_copy_vec - copy sparse vector (x := y)
|
alpar@1
|
223 |
*
|
alpar@1
|
224 |
* SYNOPSIS
|
alpar@1
|
225 |
*
|
alpar@1
|
226 |
* #include "glpios.h"
|
alpar@1
|
227 |
* void ios_copy_vec(IOSVEC *x, IOSVEC *y);
|
alpar@1
|
228 |
*
|
alpar@1
|
229 |
* DESCRIPTION
|
alpar@1
|
230 |
*
|
alpar@1
|
231 |
* The routine ios_copy_vec copies a sparse vector specified by the
|
alpar@1
|
232 |
* parameter y to a sparse vector specified by the parameter x. */
|
alpar@1
|
233 |
|
alpar@1
|
234 |
void ios_copy_vec(IOSVEC *x, IOSVEC *y)
|
alpar@1
|
235 |
{ int j;
|
alpar@1
|
236 |
xassert(x != y);
|
alpar@1
|
237 |
xassert(x->n == y->n);
|
alpar@1
|
238 |
ios_clear_vec(x);
|
alpar@1
|
239 |
x->nnz = y->nnz;
|
alpar@1
|
240 |
memcpy(&x->ind[1], &y->ind[1], x->nnz * sizeof(int));
|
alpar@1
|
241 |
memcpy(&x->val[1], &y->val[1], x->nnz * sizeof(double));
|
alpar@1
|
242 |
for (j = 1; j <= x->nnz; j++)
|
alpar@1
|
243 |
x->pos[x->ind[j]] = j;
|
alpar@1
|
244 |
return;
|
alpar@1
|
245 |
}
|
alpar@1
|
246 |
|
alpar@1
|
247 |
/***********************************************************************
|
alpar@1
|
248 |
* NAME
|
alpar@1
|
249 |
*
|
alpar@1
|
250 |
* ios_linear_comb - compute linear combination (x := x + a * y)
|
alpar@1
|
251 |
*
|
alpar@1
|
252 |
* SYNOPSIS
|
alpar@1
|
253 |
*
|
alpar@1
|
254 |
* #include "glpios.h"
|
alpar@1
|
255 |
* void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y);
|
alpar@1
|
256 |
*
|
alpar@1
|
257 |
* DESCRIPTION
|
alpar@1
|
258 |
*
|
alpar@1
|
259 |
* The routine ios_linear_comb computes the linear combination
|
alpar@1
|
260 |
*
|
alpar@1
|
261 |
* x := x + a * y,
|
alpar@1
|
262 |
*
|
alpar@1
|
263 |
* where x and y are sparse vectors, a is a scalar. */
|
alpar@1
|
264 |
|
alpar@1
|
265 |
void ios_linear_comb(IOSVEC *x, double a, IOSVEC *y)
|
alpar@1
|
266 |
{ int j, k;
|
alpar@1
|
267 |
double xj, yj;
|
alpar@1
|
268 |
xassert(x != y);
|
alpar@1
|
269 |
xassert(x->n == y->n);
|
alpar@1
|
270 |
for (k = 1; k <= y->nnz; k++)
|
alpar@1
|
271 |
{ j = y->ind[k];
|
alpar@1
|
272 |
xj = ios_get_vj(x, j);
|
alpar@1
|
273 |
yj = y->val[k];
|
alpar@1
|
274 |
ios_set_vj(x, j, xj + a * yj);
|
alpar@1
|
275 |
}
|
alpar@1
|
276 |
return;
|
alpar@1
|
277 |
}
|
alpar@1
|
278 |
|
alpar@1
|
279 |
/***********************************************************************
|
alpar@1
|
280 |
* NAME
|
alpar@1
|
281 |
*
|
alpar@1
|
282 |
* ios_delete_vec - delete sparse vector
|
alpar@1
|
283 |
*
|
alpar@1
|
284 |
* SYNOPSIS
|
alpar@1
|
285 |
*
|
alpar@1
|
286 |
* #include "glpios.h"
|
alpar@1
|
287 |
* void ios_delete_vec(IOSVEC *v);
|
alpar@1
|
288 |
*
|
alpar@1
|
289 |
* DESCRIPTION
|
alpar@1
|
290 |
*
|
alpar@1
|
291 |
* The routine ios_delete_vec deletes a sparse vector specified by the
|
alpar@1
|
292 |
* parameter v freeing all the memory allocated to this object. */
|
alpar@1
|
293 |
|
alpar@1
|
294 |
void ios_delete_vec(IOSVEC *v)
|
alpar@1
|
295 |
{ /* delete sparse vector */
|
alpar@1
|
296 |
xfree(v->pos);
|
alpar@1
|
297 |
xfree(v->ind);
|
alpar@1
|
298 |
xfree(v->val);
|
alpar@1
|
299 |
xfree(v);
|
alpar@1
|
300 |
return;
|
alpar@1
|
301 |
}
|
alpar@1
|
302 |
|
alpar@1
|
303 |
/* eof */
|