source: ThirdParty/mpqc_open/src/lib/math/scmat/blockeddiag.cc@ 00f983

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 00f983 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 8.6 KB
Line 
1//
2// blockeddiag.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#include <math.h>
29
30#include <util/misc/formio.h>
31#include <util/keyval/keyval.h>
32#include <util/state/stateio.h>
33#include <math/scmat/blocked.h>
34#include <math/scmat/cmatrix.h>
35#include <math/scmat/elemop.h>
36
37using namespace std;
38using namespace sc;
39
40/////////////////////////////////////////////////////////////////////////////
41// BlockedDiagSCMatrix member functions
42
43static ClassDesc BlockedDiagSCMatrix_cd(
44 typeid(BlockedDiagSCMatrix),"BlockedDiagSCMatrix",1,"public DiagSCMatrix",
45 0, 0, 0);
46
47void
48BlockedDiagSCMatrix::resize(SCDimension *a)
49{
50 if (mats_) {
51 delete[] mats_;
52 mats_=0;
53 }
54
55 d = a;
56
57 mats_ = new RefDiagSCMatrix[d->blocks()->nblock()];
58 for (int i=0; i < d->blocks()->nblock(); i++)
59 if (d->blocks()->size(i))
60 mats_[i] = subkit->diagmatrix(d->blocks()->subdim(i));
61}
62
63BlockedDiagSCMatrix::BlockedDiagSCMatrix(const RefSCDimension&a,
64 BlockedSCMatrixKit*k):
65 DiagSCMatrix(a,k),
66 subkit(k->subkit()),
67 mats_(0)
68{
69 resize(a);
70}
71
72BlockedDiagSCMatrix::~BlockedDiagSCMatrix()
73{
74 if (mats_) {
75 delete[] mats_;
76 mats_=0;
77 }
78}
79
80double
81BlockedDiagSCMatrix::get_element(int i) const
82{
83 int bi, bo;
84 d->blocks()->elem_to_block(i,bi,bo);
85 return mats_[bi]->get_element(bo);
86}
87
88void
89BlockedDiagSCMatrix::set_element(int i,double a)
90{
91 int bi, bo;
92 d->blocks()->elem_to_block(i,bi,bo);
93 mats_[bi]->set_element(bo,a);
94}
95
96void
97BlockedDiagSCMatrix::accumulate_element(int i,double a)
98{
99 int bi, bo;
100 d->blocks()->elem_to_block(i,bi,bo);
101 mats_[bi]->accumulate_element(bo,a);
102}
103
104void
105BlockedDiagSCMatrix::accumulate(const DiagSCMatrix*a)
106{
107 // make sure that the argument is of the correct type
108 const BlockedDiagSCMatrix* la = require_dynamic_cast<const BlockedDiagSCMatrix*>(a,
109 "BlockedDiagSCMatrix::accumulate");
110
111 // make sure that the dimensions match
112 if (!dim()->equiv(la->dim())) {
113 ExEnv::errn() << indent << "BlockedDiagSCMatrix:: accumulate(SCMatrix*a): "
114 << "dimensions don't match\n";
115 abort();
116 }
117
118 for (int i=0; i < d->blocks()->nblock(); i++)
119 if (mats_[i].nonnull())
120 mats_[i]->accumulate(la->mats_[i].pointer());
121}
122
123double
124BlockedDiagSCMatrix::invert_this()
125{
126 double det = 1.0;
127
128 for (int i=0; i < d->blocks()->nblock(); i++)
129 if (mats_[i].nonnull())
130 det *= mats_[i]->invert_this();
131
132 return det;
133}
134
135double
136BlockedDiagSCMatrix::determ_this()
137{
138 double det = 1.0;
139
140 for (int i=0; i < d->blocks()->nblock(); i++)
141 if (mats_[i].nonnull())
142 det *= mats_[i]->determ_this();
143
144 return det;
145}
146
147double
148BlockedDiagSCMatrix::trace()
149{
150 double det = 0;
151
152 for (int i=0; i < d->blocks()->nblock(); i++)
153 if (mats_[i].nonnull())
154 det += mats_[i]->trace();
155
156 return det;
157}
158
159void
160BlockedDiagSCMatrix::gen_invert_this()
161{
162 for (int i=0; i < d->blocks()->nblock(); i++)
163 if (mats_[i].nonnull())
164 mats_[i]->gen_invert_this();
165}
166
167void
168BlockedDiagSCMatrix::element_op(const Ref<SCElementOp>& op)
169{
170 BlockedSCElementOp *bop = dynamic_cast<BlockedSCElementOp*>(op.pointer());
171
172 int nb = d->blocks()->nblock();
173
174 op->defer_collect(1);
175 for (int i=0; i < nb; i++) {
176 if (bop)
177 bop->working_on(i);
178 if (mats_[i].nonnull())
179 mats_[i]->element_op(op);
180 }
181 op->defer_collect(0);
182 if (op->has_collect()) op->collect(messagegrp());
183}
184
185void
186BlockedDiagSCMatrix::element_op(const Ref<SCElementOp2>& op,
187 DiagSCMatrix* m)
188{
189 BlockedDiagSCMatrix *lm = require_dynamic_cast<BlockedDiagSCMatrix*>(m,
190 "BlockedDiagSCMatrix::element_op");
191 if (!dim()->equiv(lm->dim())) {
192 ExEnv::errn() << indent << "BlockedDiagSCMatrix: bad element_op\n";
193 abort();
194 }
195
196 BlockedSCElementOp2 *bop = dynamic_cast<BlockedSCElementOp2*>(op.pointer());
197
198 int nb = d->blocks()->nblock();
199
200 op->defer_collect(1);
201 for (int i=0; i < nb; i++) {
202 if (bop)
203 bop->working_on(i);
204 if (mats_[i].nonnull())
205 mats_[i]->element_op(op,lm->mats_[i].pointer());
206 }
207 op->defer_collect(0);
208 if (op->has_collect()) op->collect(messagegrp());
209}
210
211void
212BlockedDiagSCMatrix::element_op(const Ref<SCElementOp3>& op,
213 DiagSCMatrix* m,DiagSCMatrix* n)
214{
215 BlockedDiagSCMatrix *lm = require_dynamic_cast<BlockedDiagSCMatrix*>(m,
216 "BlockedDiagSCMatrix::element_op");
217 BlockedDiagSCMatrix *ln = require_dynamic_cast<BlockedDiagSCMatrix*>(n,
218 "BlockedDiagSCMatrix::element_op");
219
220 if (!dim()->equiv(lm->dim()) || !dim()->equiv(ln->dim())) {
221 ExEnv::errn() << indent << "BlockedDiagSCMatrix: bad element_op\n";
222 abort();
223 }
224
225 BlockedSCElementOp3 *bop = dynamic_cast<BlockedSCElementOp3*>(op.pointer());
226
227 int nb = d->blocks()->nblock();
228
229 op->defer_collect(1);
230 for (int i=0; i < nb; i++) {
231 if (bop)
232 bop->working_on(i);
233 if (mats_[i].nonnull())
234 mats_[i]->element_op(op,lm->mats_[i].pointer(),ln->mats_[i].pointer());
235 }
236 op->defer_collect(0);
237 if (op->has_collect()) op->collect(messagegrp());
238}
239
240void
241BlockedDiagSCMatrix::vprint(const char *title, ostream& os, int prec) const
242{
243 int len = (title) ? strlen(title) : 0;
244 char *newtitle = new char[len + 80];
245
246 for (int i=0; i < d->blocks()->nblock(); i++) {
247 if (mats_[i].null())
248 continue;
249
250 sprintf(newtitle,"%s: block %d",title,i+1);
251 mats_[i]->print(newtitle, os, prec);
252 }
253
254 delete[] newtitle;
255}
256
257RefSCDimension
258BlockedDiagSCMatrix::dim(int i) const
259{
260 return d->blocks()->subdim(i);
261}
262
263int
264BlockedDiagSCMatrix::nblocks() const
265{
266 return d->blocks()->nblock();
267}
268
269RefDiagSCMatrix
270BlockedDiagSCMatrix::block(int i)
271{
272 return mats_[i];
273}
274
275Ref<SCMatrixSubblockIter>
276BlockedDiagSCMatrix::local_blocks(SCMatrixSubblockIter::Access access)
277{
278 Ref<SCMatrixCompositeSubblockIter> iter
279 = new SCMatrixCompositeSubblockIter(access,nblocks());
280 for (int i=0; i<nblocks(); i++) {
281 if (block(i).null())
282 iter->set_iter(i, new SCMatrixNullSubblockIter(access));
283 else
284 iter->set_iter(i, block(i)->local_blocks(access));
285 }
286 Ref<SCMatrixSubblockIter> ret = iter.pointer();
287 return ret;
288}
289
290Ref<SCMatrixSubblockIter>
291BlockedDiagSCMatrix::all_blocks(SCMatrixSubblockIter::Access access)
292{
293 Ref<SCMatrixCompositeSubblockIter> iter
294 = new SCMatrixCompositeSubblockIter(access,nblocks());
295 for (int i=0; i<nblocks(); i++) {
296 if (block(i).null())
297 iter->set_iter(i, new SCMatrixNullSubblockIter(access));
298 else
299 iter->set_iter(i, block(i)->all_blocks(access));
300 }
301 Ref<SCMatrixSubblockIter> ret = iter.pointer();
302 return ret;
303}
304
305void
306BlockedDiagSCMatrix::save(StateOut&s)
307{
308 int ndim = n();
309 s.put(ndim);
310 int has_subblocks = 1;
311 s.put(has_subblocks);
312 s.put(nblocks());
313 for (int i=0; i<nblocks(); i++) {
314 block(i).save(s);
315 }
316}
317
318void
319BlockedDiagSCMatrix::restore(StateIn& s)
320{
321 int ndimt, ndim = n();
322 s.get(ndimt);
323 if (ndimt != ndim) {
324 ExEnv::errn() << indent
325 << "BlockedDiagSCMatrix::restore(): bad dimension" << endl;
326 abort();
327 }
328 int has_subblocks;
329 s.get(has_subblocks);
330 if (has_subblocks) {
331 int nblock;
332 s.get(nblock);
333 if (nblock != nblocks()) {
334 ExEnv::errn() << indent
335 << "BlockedDiagSCMatrix::restore(): nblock differs\n" << endl;
336 abort();
337 }
338 for (int i=0; i<nblocks(); i++) {
339 block(i).restore(s);
340 }
341 }
342 else {
343 ExEnv::errn() << indent
344 << "BlockedDiagSCMatrix::restore(): no subblocks--cannot restore"
345 << endl;
346 abort();
347 }
348}
349
350/////////////////////////////////////////////////////////////////////////////
351
352// Local Variables:
353// mode: c++
354// c-file-style: "CLJ"
355// End:
Note: See TracBrowser for help on using the repository browser.