Simbody 3.9
Loading...
Searching...
No Matches
MatrixHelper.h
Go to the documentation of this file.
1#ifndef SimTK_SIMMATRIX_MATRIX_HELPER_H_
2#define SimTK_SIMMATRIX_MATRIX_HELPER_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2005-12 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
37#include "SimTKcommon/Scalar.h"
39
40#include <iostream>
41#include <cassert>
42#include <complex>
43#include <cstddef>
44#include <utility> // for std::pair
45
46namespace SimTK {
47
48
49template <class S> class MatrixHelperRep;
50class MatrixCharacter;
52
53// ------------------------------ MatrixHelper --------------------------------
54
77
78// ----------------------------------------------------------------------------
79template <class S>
81 typedef MatrixHelper<S> This;
84public:
85 typedef typename CNT<S>::Number Number; // strips off negator from S
86 typedef typename CNT<S>::StdNumber StdNumber; // turns conjugate to complex
87 typedef typename CNT<S>::Precision Precision; // strips off complex from StdNumber
88
89 // no default constructor
90 // copy constructor suppressed
91
92 // Destructor eliminates MatrixHelperRep object if "this" owns it.
93 ~MatrixHelper() {deleteRepIfOwner();}
94
95 // Local types for directing us to the right constructor at compile time.
96 class ShallowCopy { };
97 class DeepCopy { };
98 class TransposeView { };
99 class DiagonalView { };
100
102 // "Owner" constructors //
104
105 // 0x0, fully resizable, fully uncommitted.
106 MatrixHelper(int esz, int cppEsz);
107
108 // Default allocation for the given commitment.
109 MatrixHelper(int esz, int cppEsz, const MatrixCommitment&);
110
111 // Allocate a matrix that satisfies a given commitment and has a
112 // particular initial size.
113 MatrixHelper(int esz, int cppEsz, const MatrixCommitment&, int m, int n);
114
115 // Copy constructor that produces a new owner whose logical shape and contents are
116 // the same as the source, but with a possibly better storage layout. Data will
117 // be contiguous in the copy regardless of how spread out it was in the source.
118 // The second argument is just to disambiguate this constructor from similar ones.
119 MatrixHelper(const MatrixCommitment&, const MatrixHelper& source, const DeepCopy&);
120
121 // This has the same semantics as the previous DeepCopy constructor, except that
122 // the source has negated elements with respect to S. The resulting logical shape
123 // and logical values are identical to the source, meaning that the negation must
124 // actually be performed here, using one flop for every meaningful source scalar.
125 MatrixHelper(const MatrixCommitment&, const MatrixHelper<typename CNT<S>::TNeg>& source, const DeepCopy&);
126
127
129 // External "View" constructors //
131
132 // These constructors produce a matrix which provides a view of externally-allocated
133 // data, which is known to have the given MatrixCharacter. There is also provision
134 // for a "spacing" parameter which defines gaps in the supplied data, although
135 // the interpretation of that parameter depends on the MatrixCharacter (typically
136 // it is the leading dimension for a matrix or the stride for a vector). Note
137 // that spacing is interpreted as "number of scalars between adjacent elements"
138 // which has the usual Lapack interpretation if the elements are scalars but
139 // can be used for C++ vs. Simmatrix packing differences for composite elements.
140 // The resulting handle is *not* the owner of the data, so destruction of the
141 // handle does not delete the data.
142
143 // Create a read-only view into existing data.
144 MatrixHelper(int esz, int cppEsz, const MatrixCommitment&,
145 const MatrixCharacter&, int spacing, const S* data);
146 // Create a writable view into existing data.
147 MatrixHelper(int esz, int cppEsz, const MatrixCommitment&,
148 const MatrixCharacter&, int spacing, S* data);
149
150
152 // Matrix "View" constructors //
154
155 // Matrix view constructors, read only and writable. Use these for submatrices,
156 // rows, and columns. Indices are by *element* and these may consist of multiple
157 // scalars of type template parameter S.
158
159 // "Block" views
160 MatrixHelper(const MatrixCommitment&, const MatrixHelper&, int i, int j, int nrow, int ncol);
161 MatrixHelper(const MatrixCommitment&, MatrixHelper&, int i, int j, int nrow, int ncol);
162
163 // "Transpose" views (note that this is Hermitian transpose; i.e., element
164 // type is conjugated).
166 const TransposeView&); // a read only transposed view
168 const TransposeView&); // a writable transposed view
169
170 // "Diagonal" views.
171 MatrixHelper(const MatrixCommitment&, const MatrixHelper&, const DiagonalView&); // a read only diagonal view
172 MatrixHelper(const MatrixCommitment&, MatrixHelper&, const DiagonalView&); // a writable diagonal view
173
174 // "Indexed" view of a 1d matrix.
176 int n, const int* indices);
178 int n, const int* indices);
179
180 // These invoke the previous constructors but with friendlier index source.
182 const Array_<int>& indices)
183 { new (this) MatrixHelper(mc, h, (int)indices.size(), indices.cbegin()); }
185 const Array_<int>& indices)
186 { new (this) MatrixHelper(mc, h, (int)indices.size(), indices.cbegin()); }
187
188 // "Copy" an existing MatrixHelper by making a new view into the same data.
189 // The const form loses writability, non-const retains same writability status
190 // as source. If the source is already a view then the destination will have
191 // an identical element filter so that the logical shape and values are the
192 // same for both source and copy. (The second argument is used just to
193 // disambiguate this constructor from similar ones.)
196
198 // Copy assignment //
200
201 // Behavior of copy assignment depends on whether "this" is an owner or view. If
202 // it's an owner it is resized and ends up a new, dense copy of "source" just as
203 // for the DeepCopy constructor above. If "this" is a writable view, sizes must match
204 // and we copy elements from "source" to corresponding elements of "this". If
205 // "this" is not writable then the operation will fail.
207
208 // Same as copyAssign() except the source has element types which are logically
209 // negated from the element types of "this". Since the result must have the
210 // same value as the source, this requires that all the copied elements are
211 // actually negated at a cost of one flop per scalar.
213
215 // View assignment //
217
218 // View assign always disconnects this helper from whatever view & data
219 // it used to have (destructing as appropriate) and then makes it a new view
220 // of the source. Writability is lost if the source is const, otherwise
221 // writability is inherited from the source.
224
225 // Restore helper to its just-constructed state. We forget everything except
226 // the element size and handle commitment, which can never change. The
227 // allocated helper will be the same as if we had just default-constructed
228 // using the current commitment.
229 void clear();
230
231 // Return true if there is currently no data associated with this handle.
232 bool isClear() const;
233
234 // Using *element* indices, obtain a pointer to the beginning of a particular
235 // element. This is always a slow operation compared to raw array access;
236 // use sparingly. These will fail if the indices are outside the stored
237 // portion of the matrix. Use getAnyElt() if you want something that always
238 // works.
239 const S* getElt(int i, int j) const;
240 S* updElt(int i, int j);
241
242 // Faster for 1-d matrices (vectors) if you know you have one.
243 const S* getElt(int i) const;
244 S* updElt(int i);
245
246 // This returns the correct value for any element within the logical dimensions
247 // of the matrix. In some cases it has to compute the value; in all cases
248 // it has to copy it.
249 void getAnyElt(int i, int j, S* value) const;
250
251 // Faster for 1-d matrices (vectors) if you know you have one.
252 void getAnyElt(int i, S* value) const;
253
254 // Add up all the *elements*, returning the answer in the element given
255 // by pointer to its first scalar.
256 void sum(S* eltp) const;
257 void colSum(int j, S* eltp) const;
258 void rowSum(int i, S* eltp) const;
259
260 // addition and subtraction (+= and -=)
261 void addIn(const MatrixHelper&);
262 void addIn(const MatrixHelper<typename CNT<S>::TNeg>&);
263 void subIn(const MatrixHelper&);
264 void subIn(const MatrixHelper<typename CNT<S>::TNeg>&);
265
266 // Fill all our stored data with copies of the same supplied element.
267 void fillWith(const S* eltp);
268
269 // We're copying data from a C++ row-oriented matrix into our general
270 // Matrix. In addition to the row ordering, C++ may use different spacing
271 // for elements than Simmatrix does.
272 void copyInByRowsFromCpp(const S* elts);
273
274 // Scalar operations //
275
276 // Fill every element with repeated copies of a single scalar value.
278
279 // Scalar multiply (and divide). This is useful no matter what the
280 // element structure and will produce the correct result.
281 void scaleBy(const StdNumber&);
282
283 // This is only allowed for a matrix of real or complex or neg of those,
284 // which is square, well-conditioned, and for which we have no view,
285 // and element size 1.
287
288 void dump(const char* msg=0) const; // For debugging -- comes out in a way you can feed to Matlab
289
290 // Bookkeeping //
291
292 // This is the number of logical *elements* in each column of this matrix; i.e., m.
293 int nrow() const;
294 // This is the number of *elements* in each row of this matrix; i.e., n.
295 int ncol() const;
296 // This is the total number of *elements* in the logical shape of this matrix, i.e. m*n.
297 ptrdiff_t nelt() const; // nrow*ncol
298 // This is the number of elements if this is a 1d matrix (vector or rowvector). That is,
299 // it is the same as one of nrow() or ncol(); the other must be 1. It is also the
300 // same as nelt() but limited to fit in 32 bits.
301 int length() const;
302
303 // Change the logical size of the underlying memory for this Matrix to m X n, forgetting
304 // everything that used to be there. This will fail if it would have to resize any
305 // non-resizable dimension. However, it will succeed even on non-resizable matrices and
306 // views provided the existing dimensions are already correct. If no size change is made,
307 // no action is taken and the original data is still accessible.
308 void resize(int m, int n);
309
310 // Same as resize() except as much of the original data as will fit remains in place at
311 // the same (i,j) location it had before. This may require copying the elements after
312 // allocating new space. As for resize(), this is allowed for any Matrix whose dimensions
313 // are already right, even if that Matrix is not resizable.
314 void resizeKeep(int m, int n);
315
316 void lockShape();
318
322
323 // Access to raw data. For now this is only allowed if there is no view
324 // and the raw data is contiguous.
325 bool hasContiguousData() const;
326 ptrdiff_t getContiguousDataLength() const;
327 const S* getContiguousData() const;
329
330 void replaceContiguousData(S* newData, ptrdiff_t length, bool takeOwnership);
331 void replaceContiguousData(const S* newData, ptrdiff_t length);
332 void swapOwnedContiguousData(S* newData, ptrdiff_t length, S*& oldData);
333
334 const MatrixHelperRep<S>& getRep() const {assert(rep); return *rep;}
335 MatrixHelperRep<S>& updRep() {assert(rep); return *rep;}
336 void setRep(MatrixHelperRep<S>* hrep) {assert(!rep); rep = hrep;}
338 { assert(rep); MatrixHelperRep<S>* stolen=rep; rep=0; return stolen; }
339
342
343 // Rep-stealing constructor. We're taking ownership of the supplied rep.
344 // Internal use only!
346
347private:
348 // Pointer to the private implementation object. This is the only
349 // allowable data member in this class.
350 class MatrixHelperRep<S>* rep;
351
352 // Suppress copy constructor.
354
355 // ============================= Unimplemented =============================
356 // See comment in MatrixBase::matmul for an explanation.
357 template <class SA, class SB>
358 void matmul(const StdNumber& beta, // applied to 'this'
359 const StdNumber& alpha, const MatrixHelper<SA>& A, const MatrixHelper<SB>& B);
360
361friend class MatrixHelper<typename CNT<S>::TNeg>;
362friend class MatrixHelper<typename CNT<S>::THerm>;
363};
364
365} //namespace SimTK
366
367#endif // SimTK_SIMMATRIX_MATRIX_HELPER_H_
This file defines the Array_<T,X> class and related support classes including base classes ArrayViewC...
This is a user-includable header which includes everything needed to make use of SimMatrix Scalar cod...
#define SimTK_SimTKCOMMON_EXPORT
Definition SimTKcommon/include/SimTKcommon/internal/common.h:224
The Array_<T> container class is a plug-compatible replacement for the C++ standard template library ...
Definition Array.h:1520
size_type size() const
Return the current number of elements stored in this array.
Definition Array.h:2075
const T * cbegin() const
Return a const pointer to the first element of this array if any, otherwise cend(),...
Definition Array.h:2212
Specialized information about Composite Numerical Types which allows us to define appropriate templat...
Definition CompositeNumericalTypes.h:136
K::StdNumber StdNumber
Definition CompositeNumericalTypes.h:163
K::THerm THerm
Definition CompositeNumericalTypes.h:144
K::TNeg TNeg
Definition CompositeNumericalTypes.h:139
K::Precision Precision
Definition CompositeNumericalTypes.h:164
K::Number Number
Definition CompositeNumericalTypes.h:162
A MatrixCharacter is a set containing a value for each of the matrix characteristics except element t...
Definition MatrixCharacteristics.h:597
A MatrixCommitment provides a set of acceptable matrix characteristics.
Definition MatrixCharacteristics.h:832
Definition MatrixHelper.h:49
Definition MatrixHelper.h:97
Definition MatrixHelper.h:99
Definition MatrixHelper.h:96
Definition MatrixHelper.h:98
Here we define class MatrixHelper<S>, the scalar-type templatized helper class for the more general,...
Definition MatrixHelper.h:80
MatrixHelper(const MatrixCommitment &, MatrixHelper &, int i, int j, int nrow, int ncol)
MatrixHelper(const MatrixCommitment &mc, MatrixHelper &h, const Array_< int > &indices)
Definition MatrixHelper.h:184
void rowSum(int i, S *eltp) const
void dump(const char *msg=0) const
MatrixHelper & negatedCopyAssign(const MatrixHelper< typename CNT< S >::TNeg > &)
const MatrixCommitment & getCharacterCommitment() const
const S * getElt(int i, int j) const
CNT< S >::Number Number
Definition MatrixHelper.h:85
CNT< S >::StdNumber StdNumber
Definition MatrixHelper.h:86
MatrixHelper & writableViewAssign(MatrixHelper &source)
const MatrixHelperRep< S > & getRep() const
Definition MatrixHelper.h:334
MatrixHelper(const MatrixCommitment &, const MatrixHelper &, int i, int j, int nrow, int ncol)
const S * getContiguousData() const
MatrixHelper(int esz, int cppEsz, const MatrixCommitment &)
void getAnyElt(int i, S *value) const
const MatrixCharacter & getMatrixCharacter() const
bool hasContiguousData() const
MatrixHelper(const MatrixCommitment &, const MatrixHelper< typename CNT< S >::THerm > &, const TransposeView &)
void fillWith(const S *eltp)
void addIn(const MatrixHelper< typename CNT< S >::TNeg > &)
void resizeKeep(int m, int n)
void replaceRep(MatrixHelperRep< S > *)
void subIn(const MatrixHelper &)
MatrixHelper(const MatrixCommitment &, const MatrixHelper &, int n, const int *indices)
bool isClear() const
S * updElt(int i, int j)
MatrixHelper(const MatrixCommitment &, MatrixHelper &, const DiagonalView &)
void setRep(MatrixHelperRep< S > *hrep)
Definition MatrixHelper.h:336
void sum(S *eltp) const
MatrixHelper(const MatrixCommitment &, const MatrixHelper &source, const ShallowCopy &)
MatrixHelper(const MatrixCommitment &, const MatrixHelper< typename CNT< S >::TNeg > &source, const DeepCopy &)
MatrixHelper(int esz, int cppEsz, const MatrixCommitment &, int m, int n)
void resize(int m, int n)
MatrixHelper(const MatrixCommitment &, MatrixHelper &source, const ShallowCopy &)
MatrixHelper(MatrixHelperRep< S > *)
void commitTo(const MatrixCommitment &)
CNT< S >::Precision Precision
Definition MatrixHelper.h:87
MatrixHelper & copyAssign(const MatrixHelper &source)
MatrixHelper(const MatrixCommitment &mc, const MatrixHelper &h, const Array_< int > &indices)
Definition MatrixHelper.h:181
MatrixHelper(const MatrixCommitment &, const MatrixHelper &, const DiagonalView &)
void swapOwnedContiguousData(S *newData, ptrdiff_t length, S *&oldData)
ptrdiff_t nelt() const
MatrixHelperRep< S > * stealRep()
Definition MatrixHelper.h:337
MatrixHelper(int esz, int cppEsz, const MatrixCommitment &, const MatrixCharacter &, int spacing, const S *data)
MatrixHelper(int esz, int cppEsz)
MatrixHelper(const MatrixCommitment &, MatrixHelper< typename CNT< S >::THerm > &, const TransposeView &)
ptrdiff_t getContiguousDataLength() const
void replaceContiguousData(const S *newData, ptrdiff_t length)
void getAnyElt(int i, int j, S *value) const
~MatrixHelper()
Definition MatrixHelper.h:93
void scaleBy(const StdNumber &)
void copyInByRowsFromCpp(const S *elts)
MatrixHelper(int esz, int cppEsz, const MatrixCommitment &, const MatrixCharacter &, int spacing, S *data)
void colSum(int j, S *eltp) const
MatrixHelper(const MatrixCommitment &, MatrixHelper &, int n, const int *indices)
void subIn(const MatrixHelper< typename CNT< S >::TNeg > &)
void addIn(const MatrixHelper &)
MatrixHelperRep< S > & updRep()
Definition MatrixHelper.h:335
MatrixHelper & readOnlyViewAssign(const MatrixHelper &source)
int length() const
const S * getElt(int i) const
void fillWithScalar(const StdNumber &)
void replaceContiguousData(S *newData, ptrdiff_t length, bool takeOwnership)
MatrixHelper(const MatrixCommitment &, const MatrixHelper &source, const DeepCopy &)
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition Assembler.h:37