root/trunk/multiarray/dflat/DenseVector.d

Revision 127, 9.0 kB (checked in by baxissimo, 7 years ago)

.dup handling with Views is kind of weird. Needs more looking into. Probably most views right now don't dup the data when they get .duped. Fixed DenseVector/Array?, but others probably need this too.
This was revealed by adding an opNeg to GeMatrix? and DenseVector?.
Finally the mm() templates in Blas were not distinguishable by good old brain-dead DMD.

Line 
1 /*==========================================================================
2  * densevector.d
3  *    Written in the D Programming Language (http://www.digitalmars.com/d)
4  */
5 /***************************************************************************
6  * <TODO: Module Summary>
7  *
8  * <TODO: Description>
9  *
10  * Authors:  William V. Baxter III, OLM Digital, Inc.
11  * Date: 14 Feb 2008
12  * Copyright: (C) 2008  William Baxter, OLM Digital, Inc.
13  *            Based in part on FLENS, Copyright (c) 2007, Michael Lehn
14  *            All rights reserved.
15  * License:
16  *
17  *   Redistribution and use in source and binary forms, with or without
18  *   modification, are permitted provided that the following conditions
19  *   are met:
20  *
21  *   1) Redistributions of source code must retain the above copyright
22  *      notice, this list of conditions and the following disclaimer.
23  *   2) Redistributions in binary form must reproduce the above copyright
24  *      notice, this list of conditions and the following disclaimer in
25  *      the documentation and/or other materials provided with the
26  *      distribution.
27  *   3) Neither the name of the DFLAT development group nor the names of
28  *      its contributors may be used to endorse or promote products derived
29  *      from this software without specific prior written permission.
30  *
31  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  */
43 //===========================================================================
44
45 module dflat.DenseVector;
46
47 version(Tango) import std.compat;
48
49 //import dflat.Matvec;
50 import dflat.dflat_blas;
51 import dflat.Range;
52 //import dflat.Traits;
53 import dflat.Blas;
54
55 // == DenseVector ==============================================================
56
57 import std.stdio;
58 /**
59    The A parameter is some array storage type like dflat.Array
60  */
61 struct DenseVector(A)
62 {
63 public:
64
65     alias A                            Storage;
66     alias A.View                       AView;
67     alias A.NoView                     ANoView;
68
69     alias DenseVector!(AView)          View;
70     alias DenseVector!(ANoView)        NoView;
71
72     alias A.ElementType                ElementType;
73
74     private alias A.ElementType        T; // for convenience
75
76     static DenseVector opCall() {
77         DenseVector R; return R;
78     }
79
80     static DenseVector opCall(/*const*/ ref A eng) {
81         DenseVector R; with(R) {
82             engine_ = A(eng);
83         } return R;
84     }
85
86     static if(is(A==ANoView)) {
87         // only Non-view has these constructors
88         static DenseVector opCall(int len, int firstIndex = 0) {
89             DenseVector R; with(R) {
90                 engine_ = A(len, firstIndex);
91             } return R;
92         }
93
94         static DenseVector opCall(Range r) {
95             DenseVector R; R = r;
96             return R;
97         }
98
99         void resizeOrClear(int length, int firstIndex=0)
100         {
101             engine_.resizeOrClear(length,firstIndex);
102         }
103
104         void setBeginIndex(int firstIndex)
105         {
106             engine_.setBeginIndex(firstIndex);
107         }
108
109     }
110
111     static DenseVector opCall(/*const*/ ref DenseVector rhs) {
112         DenseVector R; with(R) {
113             engine_ = A(rhs.engine_);
114         } return R;
115     }
116
117     static DenseVector opCall(/*const*/ T[] rhs) {
118         DenseVector R;
119         R = rhs;
120         return R;
121     }
122 /+
123  // needs a diff name to not conflict
124     static DenseVector opCall(E)(/*const*/ref DenseVector!(E) rhs) {
125         DenseVector R; with(R) {
126             engine_ = A(rhs.engine);
127         } return R;
128     }
129 +/
130     /+
131      static DenseVector opCall(E)(/*const*/ ref Vector!(E) rhs) {
132         DenseVector R; with(R) {
133         } return R;
134     }
135     +/
136     // -- operators --------------------------------------------------------
137
138     /+ListInitializerSwitch!(DenseVector!(A))
139     opAssign(/*const*/ref T value) {
140         return ListInitializerSwitch<DenseVector<A> >(_engine.ptr(),
141                                                       _engine.stride(),
142                                                       _engine.length(),
143                                                       value);
144     }+/
145
146     DenseVector dup() {
147         DenseVector R; R.engine_ = engine_.dup;
148         return R;
149     }
150
151     /+
152     void opAssign(RHS)(/*const*/ref Vector!(RHS) rhs)
153     {
154         copy(rhs.impl(), *this);
155         return *this;
156     }+/
157
158     /** Set the array to contain the range of numbers specified
159      */
160     void opAssign(/*const*/ref Range r)
161     {
162         assert(r.isFixed, "Relative range not allowed in this context");
163         this.resize(r);
164         int index = beginIndex();
165         for (int i=0; i<length(); ++i) {
166             *engine_.elem_ptr(index++) = cast(T)(r.begin+i*r.stride);
167         }
168     }
169
170     void opAssign(T[] arr) {
171         this.resize(arr.length);
172         int index = beginIndex();
173         // We do this slow thing because we could have a view...
174         if (this.stride!=1) {
175             for (int i=0; i<length(); ++i) {
176                 *engine_.elem_ptr(index++) = cast(T)(arr[i]);
177             }
178         }
179         else {
180             engine_.ptr[0..arr.length] = arr[0..arr.length];
181         }
182     }
183
184
185     void opAddAssign(RHS)(/*const*/ ref Vector!(RHS) rhs) {
186         axpy(cast(T)1, rhs.impl(), *this);
187     }
188
189     void opAddAssign()(T c) {
190         for (int i=beginIndex(); i<endIndex(); ++i) {
191             *engine_.elem_ptr(i) += c;
192         }
193     }
194
195     void opSubAssign(RHS)(/*const*/ ref Vector!(RHS) rhs) {
196         axpy(cast(T)(-1), rhs.impl(), *this);
197     }
198
199     void opSubAssign()(T c)
200     {
201         for (int i=beginIndex(); i<endIndex(); ++i) {
202             *engine_.elem_ptr(i) -= c;
203         }
204     }
205
206     void opMulAssign(T alpha)
207     {
208         scal_dv!(A)(alpha, *this);
209
210     }
211
212     void opDivAssign(T alpha)
213     {
214         scal_dv!(A)(cast(T)(1)/alpha, *this);
215     }
216
217     DenseVector opNeg()
218     {
219         auto ret = this.dup;
220         ret *= cast(T)-1;
221         return ret;
222     }
223
224
225     T opIndex(int index)
226     {
227         return engine_[index];
228     }
229
230     void opIndexAssign(T val, int index)
231     {
232         engine_[index] = val;
233     }
234
235     // Indexing operators
236
237     View opIndex(/*const*/ ref Range r) {
238         version(STIP) {
239             return View(engine_.view(r.begin, r.end, r.stride, r.begin));
240         }
241         else {
242             return View(engine_.view(r.begin, r.end, r.stride, beginIndex()));
243         }
244     }
245
246     View opIndex(int firstIndex, int stride, int lastIndex) {
247         version(STIP) {
248             return View(engine_.view(firstIndex, lastIndex, stride, beginIndex()));
249         }
250         else {
251             return View(engine_.view(firstIndex, lastIndex, stride, beginIndex()));
252         }
253     }
254
255     T* elem_ptr(T val, int index)
256     {
257         return engine_.elem_ptr(index);
258     }
259
260
261     // -- methods ----------------------------------------------------------
262     int beginIndex() { return engine_.beginIndex; }
263
264     int endIndex() { return engine_.endIndex; }
265
266     int length() { return engine_.length; }
267
268     int stride() { return engine_.stride; }
269
270     Range range() { return Range(beginIndex(), endIndex()); }
271
272     T *ptr() { return engine_.ptr; }
273
274     alias ptr begin; // for STL compatibility -- remove?
275
276     T * end()  // for STL compatibility -- remove?
277     { return engine_.elem_ptr(endIndex()); }
278
279     A engine() { return engine_; }
280
281     A* engine_ptr() { return &engine_; }
282
283     /** Resize vector -- for compatibility with D vectors */
284     void length(int len) { resize(len,beginIndex()); }
285
286     /** Resize vector */
287     void resize(int len, int firstIndex=0)
288     {
289         engine_.resize(len,firstIndex);
290     }
291
292     /** Resize vector to have begin/end given by Range */
293     void resize(/*const*/ref Range r)
294     {
295         engine_.resize(r.length,r.begin);
296     }
297
298     char[] toString() {
299         static if(is(typeof(A.toString))) {
300             return engine_.toString();
301         }
302         else {
303             return "[no toString]";
304         }
305     }
306
307 private:
308     A engine_;
309 }
310
311 /+
312 template <A>
313 struct TypeInfo<DenseVector<A> >
314 {
315     alias DenseVector<A> Impl;
316     alias A::ElementType ElementType;
317 }
318 +/
319
320
321
322
323 //--- Emacs setup ---
324 // Local Variables:
325 // c-basic-offset: 4
326 // indent-tabs-mode: nil
327 // End:
Note: See TracBrowser for help on using the browser.