This file is indexed.

/usr/include/sc/math/scmat/abstract.h is in libsc-dev 2.3.1-16build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
//
// abstract.h
//
// Copyright (C) 1996 Limit Point Systems, Inc.
//
// Author: Curtis Janssen <cljanss@limitpt.com>
// Maintainer: LPS
//
// This file is part of the SC Toolkit.
//
// The SC Toolkit is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// The SC Toolkit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License
// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
//
// The U.S. Government is granted a limited license as per AL 91-7.
//

#ifndef _math_scmat_abstract_h
#define _math_scmat_abstract_h

#ifdef __GNUC__
#pragma interface
#endif

#include <util/group/message.h>

#include <util/state/state.h>
#include <math/scmat/dim.h>
#include <math/scmat/block.h>
#include <iostream>

namespace sc {

class SCMatrix;
class SymmSCMatrix;
class DiagSCMatrix;
class SCVector;

class SCElementOp;
class SCElementOp2;
class SCElementOp3;

class RefSCDimension;

/** The SCMatrixKit abstract class acts as a factory for producing
matrices.  By using one of these, the program makes sure that all of the
matrices are consistent.  */
class SCMatrixKit: public DescribedClass {
  protected:
    Ref<MessageGrp> grp_;
    
  public:
    SCMatrixKit();
    SCMatrixKit(const Ref<KeyVal>&);
    ~SCMatrixKit();

    // these members are default in local.cc
    /** This returns a LocalSCMatrixKit, unless the
        default has been changed with set_default_matrixkit. */
    static SCMatrixKit* default_matrixkit();
    static void set_default_matrixkit(const Ref<SCMatrixKit> &);

    Ref<MessageGrp> messagegrp() const;

    /// Given the dimensions, create matrices or vectors.
    virtual SCMatrix* matrix(const RefSCDimension&,const RefSCDimension&) = 0;
    virtual SymmSCMatrix* symmmatrix(const RefSCDimension&) = 0;
    virtual DiagSCMatrix* diagmatrix(const RefSCDimension&) = 0;
    virtual SCVector* vector(const RefSCDimension&) = 0;

    /** Given the dimensions and a StateIn object,
        restore matrices or vectors. */
    SCMatrix* restore_matrix(StateIn&,
                             const RefSCDimension&,
                             const RefSCDimension&);
    SymmSCMatrix* restore_symmmatrix(StateIn&,
                                     const RefSCDimension&);
    DiagSCMatrix* restore_diagmatrix(StateIn&,             
                                     const RefSCDimension&);
    SCVector* restore_vector(StateIn&,
                             const RefSCDimension&);
};


/** The SCVector class is the abstract base class for
    double valued vectors. */
class SCVector: public DescribedClass {
  protected:
    RefSCDimension d;
    Ref<SCMatrixKit> kit_;
  public:
    SCVector(const RefSCDimension&, SCMatrixKit *);

    /// Save and restore this in an implementation independent way.
    virtual void save(StateOut&);
    virtual void restore(StateIn&);

    /// Return the SCMatrixKit used to create this object.
    Ref<SCMatrixKit> kit() const { return kit_; }

    // concrete functions (some can be overridden)
    /// Return a vector with the same dimension and same elements.
    virtual SCVector* copy();
    /// Return a vector with the same dimension but uninitialized memory.
    virtual SCVector* clone();

    virtual ~SCVector();
    /// Return the length of the vector.
    int n() const { return d->n(); }
    /// Return the maximum absolute value element of this vector.
    virtual double maxabs() const;
    /// Normalize this.
    virtual void normalize();
    /// Assign each element to a random number between -1 and 1
    virtual void randomize();
    /// Assign all elements of this to val.
    void assign(double val) { assign_val(val); }
    /// Assign element i to v[i] for all i.
    void assign(const double* v) { assign_p(v); }
    /** Make this have the same elements as v.  The dimensions must
        match. */
    void assign(SCVector* v) { assign_v(v); }
    /// Overridden to implement the assign functions.
    virtual void assign_val(double val);
    virtual void assign_p(const double* v);
    virtual void assign_v(SCVector *v);
    /// Assign v[i] to element i for all i.
    virtual void convert(double* v) const;
    /** Convert an SCVector of a different specialization
        to this specialization and possibly accumulate the data. */
    virtual void convert(SCVector*);
    virtual void convert_accumulate(SCVector*);
    /// Multiply each element by val.
    virtual void scale(double val);

    /// Return the RefSCDimension corresponding to this vector.
    RefSCDimension dim() const { return d; }
    /// Set element i to val.
    virtual void set_element(int i,double val) = 0;
    /// Add val to element i.
    virtual void accumulate_element(int,double) = 0;
    /// Return the value of element i.
    virtual double get_element(int i) const = 0;
    /// Sum the result of m times v into this.
    void accumulate_product(SymmSCMatrix* m, SCVector* v)
        { accumulate_product_sv(m,v); }
    void accumulate_product(SCMatrix* m, SCVector* v)
        {  accumulate_product_rv(m,v); }
    virtual void accumulate_product_sv(SymmSCMatrix* m, SCVector* v);
    virtual void accumulate_product_rv(SCMatrix* m, SCVector* v) = 0;
    /// Sum v into this.
    virtual void accumulate(const SCVector*v) = 0;
    /// Sum m into this.  One of m's dimensions must be 1.
    virtual void accumulate(const SCMatrix*m) = 0;
    /// Return the dot product.
    virtual double scalar_product(SCVector*) = 0;
    /// Perform the element operation op on each element of this.
    virtual void element_op(const Ref<SCElementOp>&) = 0;
    virtual void element_op(const Ref<SCElementOp2>&,
                            SCVector*) = 0;
    virtual void element_op(const Ref<SCElementOp3>&,
                            SCVector*,SCVector*) = 0;
    /// Print out the vector.
    void print(std::ostream&o=ExEnv::out0()) const;
    void print(const char* title=0,std::ostream&out=ExEnv::out0(),int=10) const;
    virtual void vprint(const char*title=0,std::ostream&out=ExEnv::out0(),
                        int=10) const = 0;

    /// Returns the message group used by the matrix kit
    Ref<MessageGrp> messagegrp() const;
    
    /** Returns iterators for the local (rapidly accessible) blocks used in
        this vector.  Only one iterator is allowed for a matrix is it has
        Accum or Write access is allowed.  Multiple Read iterators are
        permitted. */
    virtual Ref<SCMatrixSubblockIter> local_blocks(
        SCMatrixSubblockIter::Access) = 0;
    /// Returns iterators for the all blocks used in this vector.
    virtual Ref<SCMatrixSubblockIter> all_blocks(SCMatrixSubblockIter::Access) = 0;
};

/** The SCMatrix class is the abstract base class for general double valued
    n by m matrices.  For symmetric matrices use SymmSCMatrix and for
    diagonal matrices use DiagSCMatrix. */
class SCMatrix: public DescribedClass {
  protected:
    RefSCDimension d1,d2;
    Ref<SCMatrixKit> kit_;
  public:
    // used to control transformations
    enum Transform { NormalTransform = 0, TransposeTransform = 1 };
    
    // concrete functions (some can be overridden)
    SCMatrix(const RefSCDimension&, const RefSCDimension&, SCMatrixKit *);
    virtual ~SCMatrix();

    /// Save and restore this in an implementation independent way.
    virtual void save(StateOut&);
    virtual void restore(StateIn&);

    /// Return the SCMatrixKit used to create this object.
    Ref<SCMatrixKit> kit() const { return kit_; }

    /// Return the number of rows.
    int nrow() const { return d1->n(); }
    /// Return the number of columns.
    int ncol() const { return d2->n(); }
    /// Return the maximum absolute value element.
    virtual double maxabs() const;
    /// Assign each element to a random number between -1 and 1
    virtual void randomize();
    /// Set all elements to val.
    void assign(double val) { assign_val(val); }
    /// Assign element i, j to m[ir*nrow()+j].
    void assign(const double* m) { assign_p(m); }
    /// Assign element i, j to m[i][j].
    void assign(const double** m) { assign_pp(m); }
    /// Make this have the same elements as m. The dimensions must match.
    void assign(SCMatrix* m) { assign_r(m); }
    /// Overridden to implement to assign members.
    virtual void assign_val(double val);
    virtual void assign_p(const double* m);
    virtual void assign_pp(const double** m);
    virtual void assign_r(SCMatrix* m);
    /** Like the assign members, but these write values to the
        arguments. */
    virtual void convert(double*) const;
    virtual void convert(double**) const;
    /** Convert an SCMatrix of a different specialization to this
        specialization and possibly accumulate the data. */
    virtual void convert(SCMatrix*);
    virtual void convert_accumulate(SCMatrix*);
    /// Multiply all elements by val.
    virtual void scale(double val);
    /// Scale the diagonal elements by val.
    virtual void scale_diagonal(double val);
    /// Shift the diagonal elements by val.
    virtual void shift_diagonal(double val);
    /// Make this equal to the unit matrix.
    virtual void unit();
    /// Return a matrix with the same dimension and same elements.
    virtual SCMatrix* copy();
    /// Return a matrix with the same dimension but uninitialized memory.
    virtual SCMatrix* clone();

    // pure virtual functions
    /// Return the row or column dimension.
    RefSCDimension rowdim() const { return d1; }
    RefSCDimension coldim() const { return d2; }
    /// Return or modify an element.
    virtual double get_element(int,int) const = 0;
    virtual void set_element(int,int,double) = 0;
    virtual void accumulate_element(int,int,double) = 0;
    
    /** Return a subblock of this.  The subblock is defined as
        the rows starting at br and ending at er, and the
        columns beginning at bc and ending at ec. */
    virtual SCMatrix * get_subblock(int br, int er, int bc, int ec) =0;

    /// Assign m to a subblock of this.
    virtual void assign_subblock(SCMatrix *m, int, int, int, int, int=0, int=0) =0;

    /// Sum m into a subblock of this.
    virtual void accumulate_subblock(SCMatrix *m, int, int, int, int, int=0,int=0) =0;
    
    /// Return a row or column of this.
    virtual SCVector * get_row(int i) =0;
    virtual SCVector * get_column(int i) =0;

    /// Assign v to a row or column of this.
    virtual void assign_row(SCVector *v, int i) =0;
    virtual void assign_column(SCVector *v, int i) =0;
    
    /// Sum v to a row or column of this.
    virtual void accumulate_row(SCVector *v, int i) =0;
    virtual void accumulate_column(SCVector *v, int i) =0;
    
    /// Sum m into this.
    virtual void accumulate(const SCMatrix* m) = 0;
    virtual void accumulate(const SymmSCMatrix* m) = 0;
    virtual void accumulate(const DiagSCMatrix* m) = 0;
    virtual void accumulate(const SCVector*) = 0;
    /// Sum into this the products of various vectors or matrices.
    virtual void accumulate_outer_product(SCVector*,SCVector*) = 0;
    void accumulate_product(SCMatrix*m1,SCMatrix*m2)
        { accumulate_product_rr(m1,m2); }
    void accumulate_product(SCMatrix*m1,SymmSCMatrix*m2)
        { accumulate_product_rs(m1,m2); }
    void accumulate_product(SCMatrix*m1,DiagSCMatrix*m2)
        { accumulate_product_rd(m1,m2); }
    void accumulate_product(SymmSCMatrix*m1,SCMatrix*m2)
        { accumulate_product_sr(m1,m2); }
    void accumulate_product(DiagSCMatrix*m1,SCMatrix*m2)
        { accumulate_product_dr(m1,m2); }
    void accumulate_product(SymmSCMatrix*m1,SymmSCMatrix*m2)
        { accumulate_product_ss(m1,m2); }
    virtual void accumulate_product_rr(SCMatrix*,SCMatrix*) = 0;
    virtual void accumulate_product_rs(SCMatrix*,SymmSCMatrix*);
    virtual void accumulate_product_rd(SCMatrix*,DiagSCMatrix*);
    virtual void accumulate_product_sr(SymmSCMatrix*,SCMatrix*);
    virtual void accumulate_product_dr(DiagSCMatrix*,SCMatrix*);
    virtual void accumulate_product_ss(SymmSCMatrix*,SymmSCMatrix*);
    /// Transpose this.
    virtual void transpose_this() = 0;
    /// Return the trace.
    virtual double trace() =0;
    /// Invert this.
    virtual double invert_this() = 0;
    /// Return the determinant of this.  this is overwritten.
    virtual double determ_this() = 0;

    /** Compute the singular value decomposition for this,
        possibly destroying this. */
    virtual void svd_this(SCMatrix *U, DiagSCMatrix *sigma, SCMatrix *V);
    virtual double solve_this(SCVector*) = 0;
    virtual void gen_invert_this();

    /** Schmidt orthogonalize this.  S is the overlap matrix.
        n is the number of columns to orthogonalize. */
    virtual void schmidt_orthog(SymmSCMatrix*, int n) =0;

    /** Schmidt orthogonalize this.  S is the overlap matrix.  tol is the
        tolerance.  The number of linearly independent vectors is
        returned. */
    virtual int schmidt_orthog_tol(SymmSCMatrix*, double tol, double*res=0)=0;
    
    /// Perform the element operation op on each element of this.
    virtual void element_op(const Ref<SCElementOp>&) = 0;
    virtual void element_op(const Ref<SCElementOp2>&,
                            SCMatrix*) = 0;
    virtual void element_op(const Ref<SCElementOp3>&,
                            SCMatrix*,SCMatrix*) = 0;
    /// Print out the matrix.
    void print(std::ostream&o=ExEnv::out0()) const;
    void print(const char* title=0,std::ostream& out=ExEnv::out0(),
               int =10) const;
    virtual void vprint(const char*title=0,
                        std::ostream&out=ExEnv::out0(),int =10) const = 0;

    /// Returns the message group used by the matrix kit
    Ref<MessageGrp> messagegrp() const;
    
    /** Returns iterators for the local (rapidly accessible)
        blocks used in this matrix. */
    virtual Ref<SCMatrixSubblockIter> local_blocks(
        SCMatrixSubblockIter::Access) = 0;
    /// Returns iterators for the all blocks used in this matrix.
    virtual Ref<SCMatrixSubblockIter> all_blocks(
        SCMatrixSubblockIter::Access) = 0;
};

/** The SymmSCMatrix class is the abstract base class for symmetric
    double valued matrices. */
class SymmSCMatrix: public DescribedClass {
  protected:
    RefSCDimension d;
    Ref<SCMatrixKit> kit_;
  public:
    SymmSCMatrix(const RefSCDimension&, SCMatrixKit *);
    ~SymmSCMatrix();

    /// Return the SCMatrixKit object that created this object.
    Ref<SCMatrixKit> kit() const { return kit_; }

    /// Save and restore this in an implementation independent way.
    virtual void save(StateOut&);
    virtual void restore(StateIn&);
    /// Return the maximum absolute value element of this vector.
    virtual double maxabs() const;
    /// Assign each element to a random number between -1 and 1
    virtual void randomize();
    /// Set all elements to val.
    void assign(double val) { assign_val(val); }
    /** Assign element i, j to m[i*(i+1)/2+j]. */
    void assign(const double* m) { assign_p(m); }
    /// Assign element i, j to m[i][j].
    void assign(const double** m) { assign_pp(m); }
    /** Make this have the same elements as m.  The dimensions must
        match. */
    void assign(SymmSCMatrix* m) { assign_s(m); }
    /// Overridden to implement the assign functions
    virtual void assign_val(double val);
    virtual void assign_p(const double* m);
    virtual void assign_pp(const double** m);
    virtual void assign_s(SymmSCMatrix* m);
    /// Like the assign members, but these write values to the arguments.
    virtual void convert(double*) const;
    virtual void convert(double**) const;
    /** Convert an SCSymmSCMatrix of a different specialization
        to this specialization and possibly accumulate the data. */
    virtual void convert(SymmSCMatrix*);
    virtual void convert_accumulate(SymmSCMatrix*);
    /// Multiply all elements by val.
    virtual void scale(double);
    /// Scale the diagonal elements by val.
    virtual void scale_diagonal(double);
    /// Shift the diagonal elements by val.
    virtual void shift_diagonal(double);
    /// Make this equal to the unit matrix.
    virtual void unit();
    /// Return the dimension.
    int n() const { return d->n(); }
    /// Return a matrix with the same dimension and same elements.
    virtual SymmSCMatrix* copy();
    /// Return a matrix with the same dimension but uninitialized memory.
    virtual SymmSCMatrix* clone();

    // pure virtual functions
    /// Return the dimension.
    RefSCDimension dim() const { return d; }
    /// Return or modify an element.
    virtual double get_element(int,int) const = 0;
    virtual void set_element(int,int,double) = 0;
    virtual void accumulate_element(int,int,double) = 0;

    /** Return a subblock of this.  The subblock is defined as the rows
        starting at br and ending at er, and the columns beginning at bc
        and ending at ec. */
    virtual SCMatrix * get_subblock(int br, int er, int bc, int ec) =0;
    virtual SymmSCMatrix * get_subblock(int br, int er) =0;

    /// Assign m to a subblock of this.
    virtual void assign_subblock(SCMatrix *m, int, int, int, int) =0;
    virtual void assign_subblock(SymmSCMatrix *m, int, int) =0;

    /// Sum m into a subblock of this.
    virtual void accumulate_subblock(SCMatrix *m, int, int, int, int) =0;
    virtual void accumulate_subblock(SymmSCMatrix *m, int, int) =0;

    /// Return a row of this.
    virtual SCVector * get_row(int i) =0;

    /// Assign v to a row of this.
    virtual void assign_row(SCVector *v, int i) =0;
    
    /// Sum v to a row of this.
    virtual void accumulate_row(SCVector *v, int i) =0;

    /** Diagonalize this, placing the eigenvalues in d and the eigenvectors
        in m. */
    virtual void diagonalize(DiagSCMatrix*d,SCMatrix*m) = 0;
    /// Sum m into this.
    virtual void accumulate(const SymmSCMatrix* m) = 0;
    /// Sum into this the products of various vectors or matrices.
    virtual void accumulate_symmetric_sum(SCMatrix*) = 0;
    virtual void accumulate_symmetric_product(SCMatrix*);
    virtual void accumulate_transform(SCMatrix*,SymmSCMatrix*,
                            SCMatrix::Transform = SCMatrix::NormalTransform);
    virtual void accumulate_transform(SCMatrix*,DiagSCMatrix*, 
                            SCMatrix::Transform = SCMatrix::NormalTransform);
    virtual void accumulate_transform(SymmSCMatrix*,SymmSCMatrix*);
    virtual void accumulate_symmetric_outer_product(SCVector*);
    /** Return the scalar obtained by multiplying this on the
        left and right by v. */
    virtual double scalar_product(SCVector* v);
    /// Return the trace.
    virtual double trace() = 0;
    /// Invert this.
    virtual double invert_this() = 0;
    /// Return the determinant of this.  this is overwritten.
    virtual double determ_this() = 0;

    virtual double solve_this(SCVector*) = 0;
    virtual void gen_invert_this() = 0;

    /// Perform the element operation op on each element of this.
    virtual void element_op(const Ref<SCElementOp>&) = 0;
    virtual void element_op(const Ref<SCElementOp2>&,
                            SymmSCMatrix*) = 0;
    virtual void element_op(const Ref<SCElementOp3>&,
                            SymmSCMatrix*,SymmSCMatrix*) = 0;
    /// Print out the matrix.
    void print(std::ostream&o=ExEnv::out0()) const;
    void print(const char* title=0,std::ostream& out=ExEnv::out0(),
               int =10) const;
    virtual void vprint(const char* title=0,
                        std::ostream& out=ExEnv::out0(), int =10) const;

    /// Returns the message group used by the matrix kit
    Ref<MessageGrp> messagegrp() const;
    
    /** Returns iterators for the local (rapidly accessible)
        blocks used in this matrix. */
    virtual Ref<SCMatrixSubblockIter> local_blocks(
        SCMatrixSubblockIter::Access) = 0;
    /// Returns iterators for the all blocks used in this matrix.
    virtual Ref<SCMatrixSubblockIter> all_blocks(
        SCMatrixSubblockIter::Access) = 0;
};

/** The SymmSCMatrix class is the abstract base class for diagonal double
    valued matrices.  */
class DiagSCMatrix: public DescribedClass {
  protected:
    RefSCDimension d;
    Ref<SCMatrixKit> kit_;
  public:
    DiagSCMatrix(const RefSCDimension&, SCMatrixKit *);
    ~DiagSCMatrix();

    /// Return the SCMatrixKit used to create this object.
    Ref<SCMatrixKit> kit() const { return kit_; }

    /// Save and restore this in an implementation independent way.
    virtual void save(StateOut&);
    virtual void restore(StateIn&);

    /// Return the maximum absolute value element of this vector.
    virtual double maxabs() const;
    /// Assign each element to a random number between -1 and 1
    virtual void randomize();
    /// Set all elements to val.
    void assign(double val) { assign_val(val); }
    /// Assign element i, i to m[i].
    void assign(const double*p) { assign_p(p); }
    /** Make this have the same elements as m.  The dimensions must
        match. */
    void assign(DiagSCMatrix*d_a) { assign_d(d_a); }
    /// Overridden to implement the assign members.
    virtual void assign_val(double val);
    virtual void assign_p(const double*);
    virtual void assign_d(DiagSCMatrix*);
    /// Like the assign member, but this writes values to the argument.
    virtual void convert(double*) const;
    /** Convert an SCDiagSCMatrix of a different specialization
        to this specialization and possibly accumulate the data. */
    virtual void convert(DiagSCMatrix*);
    virtual void convert_accumulate(DiagSCMatrix*);
    /// Multiply all elements by val.
    virtual void scale(double);
    /// Return the dimension.
    int n() const { return d->n(); }
    /// Return a matrix with the same dimension and same elements.
    virtual DiagSCMatrix* copy();
    /// Return a matrix with the same dimension but uninitialized memory.
    virtual DiagSCMatrix* clone();

    // pure virtual functions
    /// Return the dimension.
    RefSCDimension dim() const { return d; }
    /// Return or modify an element.
    virtual double get_element(int) const = 0;
    virtual void set_element(int,double) = 0;
    virtual void accumulate_element(int,double) = 0;
    /// Sum m into this.
    virtual void accumulate(const DiagSCMatrix* m) = 0;
    /// Return the trace.
    virtual double trace() = 0;
    /// Return the determinant of this.  this is overwritten.
    virtual double determ_this() = 0;
    /// Invert this.
    virtual double invert_this() = 0;
    /// Do a generalized inversion of this.
    virtual void gen_invert_this() = 0;
    /// Perform the element operation op on each element of this.
    virtual void element_op(const Ref<SCElementOp>&) = 0;
    virtual void element_op(const Ref<SCElementOp2>&,
                            DiagSCMatrix*) = 0;
    virtual void element_op(const Ref<SCElementOp3>&,
                            DiagSCMatrix*,DiagSCMatrix*) = 0;
    /// Print out the matrix.
    void print(std::ostream&o=ExEnv::out0()) const;
    void print(const char* title=0,
               std::ostream& out=ExEnv::out0(), int =10) const;
    virtual void vprint(const char* title=0,
                        std::ostream& out=ExEnv::out0(), int =10) const;

    /// Returns the message group used by the matrix kit
    Ref<MessageGrp> messagegrp() const;
    
    /** Returns iterators for the local (rapidly accessible)
        blocks used in this matrix. */
    virtual Ref<SCMatrixSubblockIter> local_blocks(
        SCMatrixSubblockIter::Access) = 0;
    /// Returns iterators for the all blocks used in this matrix.
    virtual Ref<SCMatrixSubblockIter> all_blocks(
        SCMatrixSubblockIter::Access) = 0;
};

}

#endif

// Local Variables:
// mode: c++
// c-file-style: "CLJ"
// End: