GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
dRowVector.cc
Go to the documentation of this file.
1 // RowVector manipulations.
2 /*
3 
4 Copyright (C) 1994-2013 John W. Eaton
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include <iostream>
29 
30 #include "Array-util.h"
31 #include "f77-fcn.h"
32 #include "functor.h"
33 #include "lo-error.h"
34 #include "mx-base.h"
35 #include "mx-inlines.cc"
36 #include "oct-cmplx.h"
37 
38 // Fortran functions we call.
39 
40 extern "C"
41 {
42  F77_RET_T
43  F77_FUNC (dgemv, DGEMV) (F77_CONST_CHAR_ARG_DECL,
45  const double&, const double*,
46  const octave_idx_type&, const double*,
47  const octave_idx_type&, const double&,
48  double*, const octave_idx_type&
50  F77_RET_T
51  F77_FUNC (xddot, XDDOT) (const octave_idx_type&, const double*,
52  const octave_idx_type&, const double*,
53  const octave_idx_type&, double&);
54 }
55 
56 // Row Vector class.
57 
58 bool
60 {
61  octave_idx_type len = length ();
62  if (len != a.length ())
63  return 0;
64  return mx_inline_equal (len, data (), a.data ());
65 }
66 
67 bool
69 {
70  return !(*this == a);
71 }
72 
73 RowVector&
75 {
76  octave_idx_type a_len = a.length ();
77 
78  if (c < 0 || c + a_len > length ())
79  {
80  (*current_liboctave_error_handler) ("range error for insert");
81  return *this;
82  }
83 
84  if (a_len > 0)
85  {
86  make_unique ();
87 
88  for (octave_idx_type i = 0; i < a_len; i++)
89  xelem (c+i) = a.elem (i);
90  }
91 
92  return *this;
93 }
94 
95 RowVector&
96 RowVector::fill (double val)
97 {
98  octave_idx_type len = length ();
99 
100  if (len > 0)
101  {
102  make_unique ();
103 
104  for (octave_idx_type i = 0; i < len; i++)
105  xelem (i) = val;
106  }
107 
108  return *this;
109 }
110 
111 RowVector&
113 {
114  octave_idx_type len = length ();
115 
116  if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
117  {
118  (*current_liboctave_error_handler) ("range error for fill");
119  return *this;
120  }
121 
122  if (c1 > c2) { std::swap (c1, c2); }
123 
124  if (c2 >= c1)
125  {
126  make_unique ();
127 
128  for (octave_idx_type i = c1; i <= c2; i++)
129  xelem (i) = val;
130  }
131 
132  return *this;
133 }
134 
135 RowVector
136 RowVector::append (const RowVector& a) const
137 {
138  octave_idx_type len = length ();
139  octave_idx_type nc_insert = len;
140  RowVector retval (len + a.length ());
141  retval.insert (*this, 0);
142  retval.insert (a, nc_insert);
143  return retval;
144 }
145 
148 {
149  return MArray<double>::transpose ();
150 }
151 
152 RowVector
154 {
155  return do_mx_unary_op<double, Complex> (a, mx_inline_real);
156 }
157 
158 RowVector
160 {
161  return do_mx_unary_op<double, Complex> (a, mx_inline_imag);
162 }
163 
164 RowVector
166 {
167  if (c1 > c2) { std::swap (c1, c2); }
168 
169  octave_idx_type new_c = c2 - c1 + 1;
170 
171  RowVector result (new_c);
172 
173  for (octave_idx_type i = 0; i < new_c; i++)
174  result.xelem (i) = elem (c1+i);
175 
176  return result;
177 }
178 
179 RowVector
181 {
182  RowVector result (n);
183 
184  for (octave_idx_type i = 0; i < n; i++)
185  result.xelem (i) = elem (r1+i);
186 
187  return result;
188 }
189 
190 // row vector by matrix -> row vector
191 
192 RowVector
193 operator * (const RowVector& v, const Matrix& a)
194 {
195  RowVector retval;
196 
197  octave_idx_type len = v.length ();
198 
199  octave_idx_type a_nr = a.rows ();
200  octave_idx_type a_nc = a.cols ();
201 
202  if (a_nr != len)
203  gripe_nonconformant ("operator *", 1, len, a_nr, a_nc);
204  else
205  {
206  if (len == 0)
207  retval.resize (a_nc, 0.0);
208  else
209  {
210  // Transpose A to form A'*x == (x'*A)'
211 
212  octave_idx_type ld = a_nr;
213 
214  retval.resize (a_nc);
215  double *y = retval.fortran_vec ();
216 
217  F77_XFCN (dgemv, DGEMV, (F77_CONST_CHAR_ARG2 ("T", 1),
218  a_nr, a_nc, 1.0, a.data (),
219  ld, v.data (), 1, 0.0, y, 1
220  F77_CHAR_ARG_LEN (1)));
221  }
222  }
223 
224  return retval;
225 }
226 
227 // other operations
228 
229 double
230 RowVector::min (void) const
231 {
232  octave_idx_type len = length ();
233  if (len == 0)
234  return 0;
235 
236  double res = elem (0);
237 
238  for (octave_idx_type i = 1; i < len; i++)
239  if (elem (i) < res)
240  res = elem (i);
241 
242  return res;
243 }
244 
245 double
246 RowVector::max (void) const
247 {
248  octave_idx_type len = length ();
249  if (len == 0)
250  return 0;
251 
252  double res = elem (0);
253 
254  for (octave_idx_type i = 1; i < len; i++)
255  if (elem (i) > res)
256  res = elem (i);
257 
258  return res;
259 }
260 
261 std::ostream&
262 operator << (std::ostream& os, const RowVector& a)
263 {
264 // int field_width = os.precision () + 7;
265 
266  for (octave_idx_type i = 0; i < a.length (); i++)
267  os << " " /* setw (field_width) */ << a.elem (i);
268  return os;
269 }
270 
271 std::istream&
272 operator >> (std::istream& is, RowVector& a)
273 {
274  octave_idx_type len = a.length ();
275 
276  if (len > 0)
277  {
278  double tmp;
279  for (octave_idx_type i = 0; i < len; i++)
280  {
281  is >> tmp;
282  if (is)
283  a.elem (i) = tmp;
284  else
285  break;
286  }
287  }
288  return is;
289 }
290 
291 // other operations
292 
293 RowVector
294 linspace (double x1, double x2, octave_idx_type n)
295 {
296  if (n < 1) n = 1;
297 
298  NoAlias<RowVector> retval (n);
299 
300  double delta = (x2 - x1) / (n - 1);
301  retval(0) = x1;
302  for (octave_idx_type i = 1; i < n-1; i++)
303  retval(i) = x1 + i*delta;
304  retval(n-1) = x2;
305 
306  return retval;
307 }
308 
309 // row vector by column vector -> scalar
310 
311 double
312 operator * (const RowVector& v, const ColumnVector& a)
313 {
314  double retval = 0.0;
315 
316  octave_idx_type len = v.length ();
317 
318  octave_idx_type a_len = a.length ();
319 
320  if (len != a_len)
321  gripe_nonconformant ("operator *", len, a_len);
322  else if (len != 0)
323  F77_FUNC (xddot, XDDOT) (len, v.data (), 1, a.data (), 1, retval);
324 
325  return retval;
326 }
327 
328 Complex
330 {
331  ComplexRowVector tmp (v);
332  return tmp * a;
333 }